iOS開發(fā)之OC和swift互相調用

一、OC調用swift文件

  • 這里創(chuàng)建一個名為Test的OC項目

  • 在OC項目中創(chuàng)建一個swift文件Person.swift,會提示是否創(chuàng)建橋接文件。這個橋接文件是用于swift調用OC的,可以創(chuàng)建,若不創(chuàng)建則后續(xù)手動創(chuàng)建也是可以的。

  • 編譯器會為我們自動創(chuàng)建一個隱藏的Test-swift.h文件。
    1、只要在OC文件里引入這個文件就可以使用swift文件。
    2、這個文件名稱默認是:Product Module Name-Swift.h
    3、如果不希望使用默認名稱,也可以自定義,在Build Settings中找到Object-C Generated interface Header Name,這里可以自定義用于引入的swift頭文件名稱,一般格式為:Name-Swift.h,若修改了文件名稱,需重新編譯才可以識別到。注意,當工程名稱中有橫線時,會被自動轉換為下劃線。
    4、xcode會根據(jù)swift代碼生成對應的OC聲明,寫入到Name-Swift.h文件中,可以點進去查看。

  • 代碼調用

  • 1、swfit類要暴露給OC調用,這個類必須要繼承自NSObject。
    因為OC調用方法使用的是runtime的消息機制,類需要有isa指針,但是swift類是沒有的,所以要繼承自NSObject基類,才會有isa指針。

  • 2、swift類需要暴露給OC調用的成員和方法需要用@objc來修飾一下。
    具體代碼如下:

Person.swift文件代碼:

class Person: NSObject {
    @objc var age : Int = 0
    @objc  init(age: Int) {
        self.age = age
    }
}

如果覺得每個成員和方法都要用@objc來暴露太繁瑣,也可以使用@objcMembers來暴露所有的成員和方法。

@objcMembers class Person: NSObject {
    var age : Int = 0
    init(age: Int) {
        self.age = age
    }
}

OC文件調用swift代碼:

#import "Test-swift.h"

Person *p = [[Person alloc] initWithAge:10];
NSLog(@"%ld", p.age);
  • 修改暴露的成員名稱、方法名以及類名
    @objc除了可以暴露成員和方法外,還可以修改它們暴露出去的名稱,也可以修改暴露出去的類名。

swfit文件代碼

@objc(JJPerson)
@objcMembers class Person: NSObject {
    var age : Int = 0
    init(age: Int) {
        self.age = age
    }
    @objc(JJSay)
    func say() {
        print("hello")
    }
}

OC調用swift代碼

#import "JJ-swift.h"

JJPerson *p = [[JJPerson alloc] initWithAge:10];
[p JJSay];

OC文件中使用導入的swift第三方庫

導入swift第三方庫時,會自動創(chuàng)建一個不可見的文件 庫名-Swift.h

例如:
導入IQKeyboardManagerSwift三方庫,會自動生成IQKeyboardManagerSwift-Swift.h文件,在需要使用IQKeyboardManagerSwift庫的OC文件里#import "IQKeyboardManagerSwift-Swift.h"就可以使用它了。

使用示例:[IQKeyboardManager shared].enable = YES;

二、swift調用OC

  • 創(chuàng)建橋接文件
    1、一般在OC項目中第一次創(chuàng)建swift文件或者在swift項目中第一次創(chuàng)建OC文件時xcode會彈出詢問我們是否需要創(chuàng)建這個文件,點擊確定即可自動創(chuàng)建一個。
    2、默認名稱為工程名-Bridging-Header.h,我的工程名為Test所以默認為Test-Bridging-Header.h
    3、如果沒有自動創(chuàng)建,那么手動創(chuàng)建一個工程名-Bridging-Header.h文件也是可以的。
    4、如果不想使用默認的名字,也可以修改名稱,但是要在Build-Setting->Objective-C Bridging Header中將配置修改為想要的文件路徑。

  • 在橋接文件中導入供swfit調用的OC文件

  • swift文件調用OC

三、思考

  • 1、OC調用swift方法走的是runtime機制嗎?
    是!因為swift類繼承自NSObject才能讓OC使用,所以類也有isa指針,runtime消息機制就是通過isa指針來尋找方法。
    OC調用swift的JJSay方法,斷點查看匯編可以看到紅框部分的注釋,有調用objc_msgSend,這個就是OC運行時的消息發(fā)送機制。
OC調用swift方法匯編.png
  • 2、swift調用OC方法走的是runtime機制嗎?
    是!因為OC方法在.m文件里編譯,所以肯定是runtime機制。
    swift調用OC的eat方法,斷點查看匯編可以看到紅框部分的注釋,有調用objc_msgSend,這個就是OC運行時的消息發(fā)送機制。
swift調用OC方法匯編.png
  • 3、swift類繼承了NSObject,并且也用@objc或者@objcMembers暴露了方法,在swift文件里直接使用這個類的方法是走的runtime機制嗎?
    不會!
    查看匯編可以看到,調用方法這里并沒有objc_msgSend。
swift調用暴露的swift類的方法匯編.png
  • 4、swift文件調用swift方法希望它使用runtime怎么做呢?
    在方法前加上dynamic關鍵字修飾,如:dynamic func say() {print("hello")}
    查看匯編,可以看到調用say方法時的注釋有objc_msgSend。
dynamic修飾方法調用匯編.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容