现在的项目中经常需要 Swift 与 OC 混编,不管是团队内合作、调用第三方 SDK、或者是 OC 过渡 Swift,都会面临这个 Swift 与 OC 的混编,因此记录一下。
总结:
-
Swift类调用OC类:通过构建桥接头文件从而被Swift 识别而调用,将需要被 Swift 类调用 OC 类在桥接头文件中 #import **.h
-
OC 类调用 Swift 类:将 Swift 类增加动态特性,即用类用 @objcMembers
修饰或方法用@objc
修饰,同时继承NSObject
;在 OC 调用类中通过#impor "[ProjectName]-Swift.h"
类引用
下面展开说说
Swift 调用 OC
Swift 调用 OC 是通过 OC 的消息转发特性实现的,即通过OC 的 runtime 的 objc_msgSend()方法来实现的
在 Swift 工程中,新建OC 类,Xcode 会提示是否创建桥接文件,点击创建,Xcode 会自动生成一个 [ProjectName]-Bridging-Header的文件,并且会将这个文件设置在 Build Settings
中的 Swift Compiler - General
选项的 Objective-C Bridging Header
中
创建之后 **在桥接文件中 import OC 类的.h 文件,这样即可在 Swift 代码中直接调用 OC 类以及其相关方法 **。调用的过程就和 Swift 调用 Swift 类一样。
可以有了桥接文件后,调用是很顺滑的,我们还看到图二有一个 Objective-C Generated Interface Header
的配置为Swift_OC-Swift.h
这个是干啥用的呢?这个是给 OC 调用 Swift 而准备的
OC 调用 Swift
首先,被 OC 调用的 Swift 类必须是继承于 NSObject 类的,因为本身 Swift 纯粹的类是不具备 runtime 特性的,而 OC的调用过程是利用 runtime 的 objc_msgSend() 的消息转发,因此要保留其动态性,就需要继承于 NSObject 类。
其次,被OC 调用Swift类的属性以及方法需要加上 @objc
修饰,原因和之前说过的 Swift 中使用 KVO 是一样的,为了告诉编译器这个属性、方法是保留动态特性的。
第三, 要在 OC 类中调用 Swift 类,需要 在 OC 类中 #import <项目名>-Swift.h
即前面图二中的所说的 Objective-C Generated Interface Header
配置的值
注意在
#import <项目名>-Swift.h
之前要编译一下,否则工程还没有编译桥接上相关文件,该文件也还未存在,会报找不到文件的错误。
用以上指定的 属性以及 指定的方法 用 @objc
修饰的方法,当一个类的属性多了或者对外 API 多了之后,那边每一个属性每一个方法都需要加上 @objc
修饰就有点低效了。苹果提供了另外的一种方式,可以将整个类的 open 属性以及方法都保留 动态特性。通过在类声明前面加上 @objcMembers
修饰
以上是 Swift 项目 调用 OC 类的处理,那么 OC 项目调用Swift 类如何呢?
其实都是一样的,桥接文件,以及双方的调用关系处理都是一模一样的,毕竟都是不是 OC 调用 Swift 就是 Swift 调用 OC,所以也无所谓以什么语言为主的项目。
需要注意的是,Swift 类如果要想被 OC 调用,最终都是需要实现 runtime 特性,即:
-
继承 NSObject
-
类使用 @objcMembers
修饰,或者 方法使用@bojc
修饰 -
如果是三方库,需要公开的 API则需要在类 前面添加 public
修饰,且在公开的 API 方法前面添加public
修饰
(好像之前发过了,再发一遍吧🤓,毕竟最近做flutter用的比较多)
原文始发于微信公众号(三万之一):Swift 与 OC 混编
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/231198.html