第三十六章 Swift 与OC交互

如果不可避免需要混编,那么我们需要了解一些知识来降低不同语言之间的差异。

1. OC 导入 Swift

OC项目如果想要将某个类导入Swift,那么仅需要创建桥接文件(一般创建第一个Swift文件时会提示,点击同意后会自动创建以及进行配置),将对应的头文件添加进去即可。

// Project-Bridging-Swift.h
//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "Model.h"

此时Swift便可调用该类(一般需要先编译一下才能被编译器语法糖发现)。

注意:Swfit仅支持OC类,不支持C++类,如有需要,你需要先封装成OC类。


由于OC没有命名空间,一般都会携带前缀,但Swift并不需要,所以我们可以NS_SWIFT_NAME重命名。

@interface PKModel : NSObject

@end

// let model = PKModel()

如果我们不希望有PK前缀,可以利用宏NS_SWIFT_NAME来重命名

NS_SWIFT_NAME(Model)
@interface PKModel : NSObject

@end

// let model = Model()

那么Swift重该类便是Model,而非PKModel

该宏同样可以给函数命名。

let model = Model()

- (void)testWithContent:(nullable id)content value:(double)value status:(int)status;
model.test(withContent: Any?, value: Double, status: Int32)

- (void)testWithContent:(nullable id)content value:(double)value status:(int)status NS_SWIFT_NAME(test(content:value:status:));
model.test(content: Any?, value: Double, status: Int32)

2. Swift 导入 OC

Swift 导入 OC相对就要复杂一些,需要满足以下条件。

  • 必须继承与NSObject并添加@objc,无论想要暴露的是类还是属性还是函数。
  • 暴露出的类型必须是OC所支持的,即基本类型和NSObject子类,struct等无法暴露。
  • 权限必须是internal及以上。
  • 需要使用Swift类需要导入ProjectName-Swift.h文件(ProjectName是你的项目名)。

注意:元组可以暴露给OC,但无法使用,能打印出来。


我们可以利用@objc来重命名导入OC的类

@objc(PKPerson class Person: NSObject {
    @objc(logWithMessage:) func log(message: String?) {
        print(message ?? "")
    }
}

PKPerson *person = [[PKPerson alloc] init];
[person logWithMessage:@"food"]; // "food"

如果有一些不想暴露给OC的内容,可以添加@nonobjc

@objc(PKPerson) class Person: NSObject {
    @nonobjc func log(message: String?) {
        print(message ?? "")
    }
}

[PKPerson.new log:@"food"]; // No visible @interface for 'PKPerson' declares the selector 'logWithMessage:'

你可能感兴趣的:(第三十六章 Swift 与OC交互)