如果不可避免需要混编,那么我们需要了解一些知识来降低不同语言之间的差异。
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:'
网友评论