Swift 类使用 Objective-C 类使用 Swift 类 [英] Swift class using Objective-C class using Swift class
问题描述
我有一个 obj-c 项目,我成功地向其中添加了一个新的 Swift 类 A,该类正被一些现有的 obj-c 类 B 使用 - 使用自动生成的MyProject-Swift.h"标头作为预期.
I have an obj-c project to which I successfully added a new Swift class A, which is being used by some existing obj-c class B - the use of the automatically generated "MyProject-Swift.h" header worked as expected.
我还成功添加了一个新的 Swift 类 C,它使用了一些现有的 obj-c 类 D - 桥接头的使用也按预期工作.
I also successfully added a new Swift class C that uses some existing obj-c class D - the use of the bridging header also worked as expected.
然而,假设我想从我的 Swift 类 C 引用现有的 obj-c 类 B(它又引用新的 Swift 类 A).为了做到这一点,我需要将B.h"导入到桥接头中.但是,如果我这样做,我会在 B 类中收到错误消息:未找到‘MyProject-Swift.h’文件"(即不再生成该文件).
However, suppose I want to refer from my Swift class C to the existing obj-c class B (which in turn refers to the new Swift class A). In order to do that I need to import "B.h" to the bridging header. However, if I do that I get an error in class B: "'MyProject-Swift.h' file not found" (i.e., the file is no longer generated).
我做错了什么还是这是 Swift 和 Objective-C 之间不允许的一种交互?好像有一种编译器无法解决的循环引用.
Am I doing something wrong or is this a kind of interaction between Swift and Objective-C that is not allowed? It looks like there is a kind of circular reference that the compiler is unable to solve.
--- 编辑---
我会尝试通过添加一些代码来使问题更清楚.
I'll try to make the question clearer by adding some code.
-- 序言 --
我向 obj-c 项目添加了一个新的 Swift 类:
I added a new Swift class to an obj-c project:
// SwiftClassA.swift
import Foundation
@objc class SwiftClassA : NSObject {
var myProperty = 0
}
代码正确编译并在自动生成的MyProject-Swift.h"头文件中被翻译成 obj-c 存根,如下所示:
The code compiles correctly and is translated into obj-c stubs in the automatically generated "MyProject-Swift.h" header like so:
// MyProject-Swift.h
...
SWIFT_CLASS("_TtC7MyProject11SwiftClassA")
@interface SwiftClassA : NSObject
@property (nonatomic) NSInteger myProperty;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
现在,一个 obj-c 类使用 SwiftClassA:
Now, one obj-c class uses 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 类来引用使用 Swift 类 SwiftClassA 的 obj-c 类 (ObjCClass) 吗?
Can I now create a new Swift class that refers to the obj-c class (ObjCClass) that is using the Swift class SwiftClassA?
这是我做不到的.
如果我添加新的 Swift 类:
If I add the new 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)")
}
}
这当然不会编译,因为使用未解析的标识符‘ObjCClass’".所以我需要将它添加到桥接头文件中:
this of course won't compile because of "Use of unresolved identifier 'ObjCClass'". So I need to add that to the bridging header file:
// BridgingHeader.h
#ifndef MyProject_BridgingHeader_h
#define MyProject_BridgingHeader_h
...
#import "ObjCClass.h"
#endif
但是,如果我这样做,ObjCClass.h 文件将无法编译并给出未找到‘MyProject-Swift.h’文件".
However, if I do that, the ObjCClass.h file won't compile giving a "'MyProject-Swift.h' file not found".
我在几个地方读到过(虽然没有例子),这可能意味着存在循环引用,并且使用@class 的前向引用可以解决问题.但是,我不确定需要前向引用的内容和位置,我所有的尝试都失败了.
I've read in several places (with no example, though) that this may mean that there is a circular reference and that a forward reference using @class could solve the problem. However, I'm not sure what needs to be forward referenced and where, and all my attempts failed.
我希望这个问题现在不再令人困惑!
I hope the question is no longer confusing now!
推荐答案
这是一个典型的循环引用问题.
This is a typical cyclical referencing problem.
请仔细阅读文档:
为避免循环引用,不要将 Swift 导入 Objective-C 头文件.相反,您可以转发声明一个 Swift 类以在 Objective-C 标头中使用它.请注意,您不能在 Objective-C 中继承 Swift 类.
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
:
So, you should use "forward declare" in .h
, and #import
in .m
:
// 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
这篇关于Swift 类使用 Objective-C 类使用 Swift 类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!