Swift与OC混编

Posted 滴水微澜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift与OC混编相关的知识,希望对你有一定的参考价值。

Swift调OC
 
在Swift项目中调用OC类中的方法需要有个targetName-Bridging-Header.h文件,在这个文件中导入OC要暴露给Swift的类。
targetName-Bridging-Header.h文件的创建有2种方式
1.自己手动创建,然后在配置文件的Object-C Bridging Header中添加这个targetName-Bridging-Header.h文件的路径
2.在Swift项目工程中创建一个OC类,此时Xcode会自动帮助创建。
 
3.在Swift中使用OC类
import UIKit

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let p = Person();
        p.name = "jack";
        p.age = 11;
        p.say();
    
如果自己在OC中定义的C语言函数名字和Swift运行中的函数名一样,冲突时,可以使用@_silgen_name将C函数的名字进行重新成Swift的另一个函数名,供Swift中使用。
@_silgen_name("sum") func swift_sum(a: Int, b: Int) -> Int

 

OC调Swift
Swift项目在创建时就默认生成了一个targetName-Swift.h文件,用于暴露Swift类给OC使用。注意这里的targetName不允许使用-链接单词,如果出现这种情况会把-自动改成_进行单词连接。
如下,当前项目名是Swift-OC,而targetName被自动改成了Swift_OC。
 
Swift暴露给OC类使用时需要做一定的修改。
1.要暴露的类需要继承自NSObject
2.要暴露成员变量和方法给OC时,需要加@objc声明。
3.要暴露全部信息时,包含成员变量和方法以及扩展中的信息,则要在类前面加@objcMembers进行声明。
@objcMembers class Car: NSObject 
    var speed: Float;
    var name: String;
    
    init(speed: Float, name: String) 
        self.speed = speed;
        self.name = name;
    
    
    func run() -> Void 
        print("出发,时速:\\(self.speed)")
    


extension Car 
    func circleRun() 
        print("跑圈,时速:\\(self.speed)")
    
 
Swift中@objc的使用
可以使用@objc重命名swift暴露给oc的方法
selector是oc的runtime里使用的一套东西,只有swift中的类暴露给OC是才能正常使用。
@objcMembers class Car: NSObject 
    var speed: Float;
    @objc(bigName) //重写暴露给OC的方法
    var name: String;
    
    init(speed: Float, name: String) 
        self.speed = speed;
        self.name = name;
    
    
    func run() -> Void 
        print("出发,时速:\\(self.speed)")
    
    
    func runPerform() -> Void 
        perform(#selector(run))
    


extension Car 
    @objc(bigRun)
    func circleRun() 
        print("跑圈,时速:\\(self.speed)")
    
Swift中被@objc 修改的协议可以被OC实现
@objc protocol RunProtocol 
Swift的类中中被@objc dynamic 修改的方法 走runtime的那套消息发送机制
class Computer: NSObject 
    @objc dynamic func work(num: Int) 
        print("工作时长:\\(num)")
    
Swift的类中中被@objc dynamic 修改的属性可以进行KVC/KVO
class Person: NSObject 
    @objc dynamic var age: Int = 10
    
    override init() 
        super.init()
        self.addObserver(self, forKeyPath: "age", options: .new, context: nil)
    
    
    override class func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) 
        print("observer回调:\\(change!)")
    
    
    deinit 
        self.removeObserver(self, forKeyPath: "age")
    
Swift与OC互相调用理解
 
1.Swift要暴露给OC调用,为什么要继承自NSObject?
OC的方法调用走的runtime的objc_sendMsg(), 这就需要isa指针, 而NSObject中有isa指针,所以要继承自NSObject
 
2.Swift调用OC桥接类的方法是怎么调用的,OC调用Swift暴露的方法又是如何调用的?
Swift调用自己定义的纯Swift方法底部走的是C++虚函数表那套。
Swift调用OC桥接类的方法底层走的还是OC的objc_msgSender机制,因为OC文件被编译后是转换的消息发送代码。
OC调用Swift暴露的方法时,因为是继承自NSObject, 所以底部走的还是objc_sendMsg机制
 
3.对于Swift类继承了NSObject,再在swift调用时,是怎么调用的?
底层走的还是Swift的需函数表那套,这套性能更高。
 
如何让Swift的方法走Runtime的消息转发机制呢?
通过在方法前面添加dynamic修饰
@objcMembers class Car: NSObject 
    var speed: Float;
    @objc(bigName) //重写暴露给OC的方法
    var name: String;
    
    init(speed: Float, name: String) 
        self.speed = speed;
        self.name = name;
    
        
    dynamic func fillOil() -> Void 
        print("加油")
    

 

 
 
 

swift与OC混编

参考技术A swift与OC混编的总结

现在的swift开发多数会用到混编。swift和oc是通过桥接文件来实现的。无论是在oc创建的项目中还中创建swift文件,还是在swift文件中创建oc文件,第一次都会自动提示建立桥接文件。名字为:xxx-Bridging-Header.h,并且自动添加文件路径。如果是导入另一只中语言的第三方库,就不会自动生成桥接文件,这时候就需要自己建立一个桥接文件。第一步:新建一个”.h”文件,也就是新建中的”Header.h“文件,名字可以模仿系统的写法”xxx(demo名字)-Bridging-Header.h“;第二步,桥接文件路径,在设置Build Settings 中搜索Bridging,结果中Objective-C Brindging Header 中拖入文件路径(前面的可以写成$(SRCROOT)/,这样就会自动生成项目文件路径,不会因为换了电脑就找不到文件路径),编译一下,就可以了。

在oc项目中引用swift文件,只需导入头文件

#import "项目名字-Swift.h"

1

1

这个文件是隐藏的,在工程中看不见。导入这个文件后就可以在oc使用swift写的类了。

在swift文件中引用oc的类,在桥接文件中引入需要引用oc的类的头文件,编译一下,就可以使用oc的类了。

以上是关于Swift与OC混编的主要内容,如果未能解决你的问题,请参考以下文章

swift与oc混编

OC与Swift混编

iOS oc与swift组件混编方案

Swift与OC的混编

Swift 与 OC 混编

Swift与OC混编