Swift class 使用 Objective-C class 使用 Swift class
Swift class using Objective-C class using Swift class
我有一个 obj-c 项目,我成功地向其中添加了一个新的 Swift class A,它正在被一些现有的 obj-c class 使用B - 使用自动生成的 "MyProject-Swift.h" header 按预期工作。
我还成功添加了一个新的 Swift class C,它使用了一些现有的 obj-c class D - 使用桥接 header 也有效不出所料。
但是,假设我想从我的 Swift class C 引用现有的 obj-c class B(反过来又引用新的 Swift class A).为此,我需要将 "B.h" 导入桥接 header。但是,如果我这样做,我会在 class B 中收到错误消息:“找不到 'MyProject-Swift.h' 文件”(即不再生成文件)。
我是不是做错了什么,或者这是 Swift 和 Objective-C 之间的一种不允许的互动?好像有一种编译器无法解决的循环引用。
--- 编辑 ---
我会尝试通过添加一些代码使问题更清楚。
-- 序言 --
我向 obj-c 项目添加了一个新的 Swift class:
// SwiftClassA.swift
import Foundation
@objc class SwiftClassA : NSObject {
var myProperty = 0
}
代码编译正确,并在自动生成的 "MyProject-Swift.h" header 中翻译成 obj-c 存根,如下所示:
// MyProject-Swift.h
...
SWIFT_CLASS("_TtC7MyProject11SwiftClassA")
@interface SwiftClassA : NSObject
@property (nonatomic) NSInteger myProperty;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
现在,一个 obj-c class 使用 SwiftClassA:
// ObjCClass.h
#import <Foundation/Foundation.h>
#import <MyProject-Swift.h>
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
这也可以无缝工作。
-- 问题 --
我现在可以创建一个新的 Swift class 来引用正在使用 Swift [=75 的 obj-c class (ObjCClass) =] SwiftA 类?
这是我做不到的。
如果我添加新的 Swift class:
// SwiftClassB.swift
import Foundation
@objc class SwiftClassB : NSObject {
var aPropertyOfClassB = 1
func someFunc() {
var objCObject = ObjCClass()
var theProperty = objCObject.aProperty
print("The property is \(theProperty)")
}
}
这当然不会编译,因为 "Use of unresolved identifier 'ObjCClass'"。所以我需要将其添加到桥接 header 文件中:
// BridgingHeader.h
#ifndef MyProject_BridgingHeader_h
#define MyProject_BridgingHeader_h
...
#import "ObjCClass.h"
#endif
但是,如果我这样做,ObjCClass.h 文件将无法编译并给出“'MyProject-Swift.h' 文件未找到”。
我在几个地方读到过(虽然没有示例)这可能意味着存在循环引用并且使用@class 的前向引用可以解决问题。但是,我不确定需要向前引用什么以及在哪里,我的所有尝试都失败了。
我希望这个问题现在不再令人困惑!
这是一个典型的循环引用问题。
仔细阅读the docs:
To avoid cyclical references, don’t import Swift into an Objective-C header file. Instead, you can forward declare a Swift class to use it in an Objective-C header. Note that you cannot subclass a Swift class in Objective-C.
因此,您应该在 .h
中使用 "forward declare",在 .m
中使用 #import
:
// ObjCClass.h
#import <Foundation/Foundation.h>
@class SwiftClassA;
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
// ObjCClass.m
#import "ObjCClass.h"
#import "MyProject-Swift.h"
@implementation ObjCClass
// your code
@end
我有一个 obj-c 项目,我成功地向其中添加了一个新的 Swift class A,它正在被一些现有的 obj-c class 使用B - 使用自动生成的 "MyProject-Swift.h" header 按预期工作。
我还成功添加了一个新的 Swift class C,它使用了一些现有的 obj-c class D - 使用桥接 header 也有效不出所料。
但是,假设我想从我的 Swift class C 引用现有的 obj-c class B(反过来又引用新的 Swift class A).为此,我需要将 "B.h" 导入桥接 header。但是,如果我这样做,我会在 class B 中收到错误消息:“找不到 'MyProject-Swift.h' 文件”(即不再生成文件)。
我是不是做错了什么,或者这是 Swift 和 Objective-C 之间的一种不允许的互动?好像有一种编译器无法解决的循环引用。
--- 编辑 ---
我会尝试通过添加一些代码使问题更清楚。
-- 序言 --
我向 obj-c 项目添加了一个新的 Swift class:
// SwiftClassA.swift
import Foundation
@objc class SwiftClassA : NSObject {
var myProperty = 0
}
代码编译正确,并在自动生成的 "MyProject-Swift.h" header 中翻译成 obj-c 存根,如下所示:
// MyProject-Swift.h
...
SWIFT_CLASS("_TtC7MyProject11SwiftClassA")
@interface SwiftClassA : NSObject
@property (nonatomic) NSInteger myProperty;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
现在,一个 obj-c class 使用 SwiftClassA:
// ObjCClass.h
#import <Foundation/Foundation.h>
#import <MyProject-Swift.h>
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
这也可以无缝工作。
-- 问题 --
我现在可以创建一个新的 Swift class 来引用正在使用 Swift [=75 的 obj-c class (ObjCClass) =] SwiftA 类?
这是我做不到的。
如果我添加新的 Swift class:
// SwiftClassB.swift
import Foundation
@objc class SwiftClassB : NSObject {
var aPropertyOfClassB = 1
func someFunc() {
var objCObject = ObjCClass()
var theProperty = objCObject.aProperty
print("The property is \(theProperty)")
}
}
这当然不会编译,因为 "Use of unresolved identifier 'ObjCClass'"。所以我需要将其添加到桥接 header 文件中:
// BridgingHeader.h
#ifndef MyProject_BridgingHeader_h
#define MyProject_BridgingHeader_h
...
#import "ObjCClass.h"
#endif
但是,如果我这样做,ObjCClass.h 文件将无法编译并给出“'MyProject-Swift.h' 文件未找到”。
我在几个地方读到过(虽然没有示例)这可能意味着存在循环引用并且使用@class 的前向引用可以解决问题。但是,我不确定需要向前引用什么以及在哪里,我的所有尝试都失败了。
我希望这个问题现在不再令人困惑!
这是一个典型的循环引用问题。
仔细阅读the docs:
To avoid cyclical references, don’t import Swift into an Objective-C header file. Instead, you can forward declare a Swift class to use it in an Objective-C header. Note that you cannot subclass a Swift class in Objective-C.
因此,您应该在 .h
中使用 "forward declare",在 .m
中使用 #import
:
// ObjCClass.h
#import <Foundation/Foundation.h>
@class SwiftClassA;
@interface ObjCClass : NSObject
@property (nonatomic, strong) SwiftClassA *aProperty;
@property (nonatomic) int *aNumber;
@end
// ObjCClass.m
#import "ObjCClass.h"
#import "MyProject-Swift.h"
@implementation ObjCClass
// your code
@end