第三十六章 Swift 与OC交互

2019-06-12  本文已影响0人  我有小尾巴快看

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

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相对就要复杂一些,需要满足以下条件。

注意:元组可以暴露给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:'

上一篇 下一篇

猜你喜欢

热点阅读