Swift 类使用 Objective-C 类使用 Swift 类

Posted

技术标签:

【中文标题】Swift 类使用 Objective-C 类使用 Swift 类【英文标题】:Swift class using Objective-C class using Swift class 【发布时间】:2015-01-04 01:19:18 【问题描述】:

我有一个 obj-c 项目,我成功地添加了一个新的 Swift 类 A,它被一些现有的 obj-c 类 B 使用 - 使用自动生成的“MyProject-Swift.h”头文件作为预计。

我还成功添加了一个新的 Swift 类 C,它使用了一些现有的 obj-c 类 D - 桥接头的使用也按预期工作。

但是,假设我想从我的 Swift 类 C 引用现有的 obj-c 类 B(它又引用新的 Swift 类 A)。为此,我需要将“B.h”导入桥接头。但是,如果我这样做,我会在 B 类中收到错误:“'MyProject-Swift.h' 文件未找到”(即不再生成该文件)。

是我做错了什么,还是这种 Swift 和 Objective-C 之间不允许的交互?貌似有一种循环引用是编译器无法解决的。

--- 编辑 ---

我会尝试通过添加一些代码使问题更清楚。

-- 序言--

我在一个 obj-c 项目中添加了一个新的 Swift 类:

//  SwiftClassA.swift
import Foundation
@objc class SwiftClassA : NSObject 
    var myProperty = 0

代码正确编译并在自动生成的“MyProject-Swift.h”头文件中转换为obj-c存根,如下所示:

// MyProject-Swift.h
...
SWIFT_CLASS("_TtC7MyProject11SwiftClassA")
@interface SwiftClassA : NSObject
@property (nonatomic) NSInteger myProperty;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

现在,一个 obj-c 类使用 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) 吗?

这是我做不到的。

如果我添加新的 Swift 类:

//  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'”。所以我需要将它添加到桥接头文件中:

//  BridgingHeader.h
#ifndef MyProject_BridgingHeader_h
#define MyProject_BridgingHeader_h
...
#import "ObjCClass.h"
#endif

但是,如果我这样做,ObjCClass.h 文件将无法编译,并给出“'MyProject-Swift.h' 文件未找到”。

我在几个地方读到过(虽然没有示例),这可能意味着存在循环引用,并且使用 @class 的前向引用可以解决问题。但是,我不确定需要前向引用的内容和位置,并且我的所有尝试都失败了。

我希望这个问题现在不再令人困惑!

【问题讨论】:

我不认为这个问题是不恰当的或不清楚的,而且这个问题是真实的并且是真正感兴趣的(至少对我来说)。我不反对投票,但请您至少告诉我这个问题有什么问题吗?如果是副本,副本在哪里?如果太明显,答案是什么?谢谢 以目前的形式,这个问题非常令人困惑。 这个问题在我看来是合理的。 【参考方案1】:

这是一个典型的循环引用问题。

注意阅读the docs:

为避免循环引用,不要将 Swift 导入到 Objective-C 头文件中。相反,您可以转发声明一个 Swift 类以在 Objective-C 标头中使用它。请注意,您不能在 Objective-C 中继承 Swift 类。

所以,你应该在.h 中使用“前向声明”,在.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

【讨论】:

以上是关于Swift 类使用 Objective-C 类使用 Swift 类的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中使用 Objective-C 扩展类

在 Objective-C 中使用 Swift 类

在 Objective-C 中使用通用 Swift 类

在 Objective-c 中使用 swift 类

无法在 Swift 中扩展 Objective-C 类

如何使用可用于 Swift 类的 std:vector 制作 Objective-c 类