一、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ā)送機制。

-
2、swift調用OC方法走的是runtime機制嗎?
是!因為OC方法在.m文件里編譯,所以肯定是runtime機制。
swift調用OC的eat方法,斷點查看匯編可以看到紅框部分的注釋,有調用objc_msgSend,這個就是OC運行時的消息發(fā)送機制。

-
3、swift類繼承了NSObject,并且也用@objc或者@objcMembers暴露了方法,在swift文件里直接使用這個類的方法是走的runtime機制嗎?
不會!
查看匯編可以看到,調用方法這里并沒有objc_msgSend。

-
4、swift文件調用swift方法希望它使用runtime怎么做呢?
在方法前加上dynamic關鍵字修飾,如:dynamic func say() {print("hello")}
查看匯編,可以看到調用say方法時的注釋有objc_msgSend。
