Swift開發(fā)是一種大趨勢了浇揩,每年Apple都會發(fā)布新的版本台妆。但是它的第三方庫還是沒有Objective-C的多扶叉,而且想用老項(xiàng)目中的工具類或框架,該怎么辦呢逼裆?
這就需要Swift&Objective-C混編互調(diào)了郁稍,但是在Objective-C的編譯器主要可以識別以下幾種擴(kuò)展名的文件:
- .m文件,可以編寫Objective-C代碼或者C語言代碼胜宇;
- .cpp文件耀怜,C++文件恢着,只能識別C++或者C語言代碼;
- .mm财破,主要用于編寫C++和Objective-C混編的代碼掰派,可以同時(shí)識別Objective-C、C和C++代碼左痢。
那么該怎么讓Swift&Objective-C混編互調(diào)呢靡羡?在Apple發(fā)布Swift的時(shí)候已經(jīng)提供了方案,在iOS8以后Apple給出了這兩種語言之間的橋接方案俊性,簡單來說就是在Swift工程中略步,通過提示創(chuàng)建的Bridging頭文件可以將Objective-C文件和Swift文件銜接在一起,從而可以在Objective-C文件中引用Swift類定页,或者在Swift文件中引用Objective-C的類趟薄。
下面我們一起來具體操作一下:
1. 創(chuàng)建一個(gè)Swift工程,選擇Single View App
2. 先新建一個(gè)swift類
新建類SwiftObjct.swift典徊,包含一個(gè)屬性杭煎,一個(gè)實(shí)例方法,一個(gè)類方法:
import UIKit
class SwiftObjct: NSObject
{
var name = "swiftObject"
func instanceMethod( ) -> Void
{
print("swift instance method")
}
class func classMethod( ) -> Void
{
print("swift class method")
}
}
3. 創(chuàng)建第一個(gè)OC類時(shí)會提示創(chuàng)建一個(gè)bridging header文件
會自動(dòng)生成一個(gè)頭文件 SwiftObjectiveC-Bridging-Header.h(前綴是工程名)
再創(chuàng)建一個(gè)Objective-C類OCObject卒落,同樣包含一個(gè)屬性羡铲,一個(gè)實(shí)例方法,一個(gè)類方法:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface OCObject : NSObject
@property (nonatomic,strong) NSString *name;
-(void)instanceMethod;
+(void)classMethod;
@end
NS_ASSUME_NONNULL_END
4. Swift類調(diào)用Objective-C的類
在工程自動(dòng)生成的類ViewController.swift中調(diào)用我們剛創(chuàng)建的Objective-C的類OCObject
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let ocObject = OCObject();
ocObject.instanceMethod()
OCObject.classMethod()
}
}
此時(shí)編譯器會報(bào)錯(cuò)Use of unresolved identifier 'OCObject'
儡毕,原因是我們還沒有把Objective-C的類和Swift關(guān)聯(lián)起來也切。在創(chuàng)建第一個(gè)Objective-C類OCObject的時(shí)候生成的頭文件SwiftObjectiveC-Bridging-Header.h,就是連接它們的橋梁妥曲。
在頭文件中導(dǎo)入剛創(chuàng)建的Objective-C類OCObject:
#import "OCObject.h"
然后一定要command+B編譯通過一下贾费,此時(shí)ViewController.swift調(diào)用的OCObject就不再報(bào)錯(cuò)了。
5. Objective-C類調(diào)用Swift類
上一步建立的連接之后檐盟,接下來我們在OCObject.m實(shí)現(xiàn)它的兩個(gè)方法褂萧,并調(diào)用SwiftObjct:
-(void)instanceMethod
{
SwiftObjct *swiftObject = [[SwiftObjct alloc] init];
[swiftObject instanceMethod];
NSLog(@"oc instance method, swiftObjct.name=%@", swiftObject.name);
}
+(void)classMethod
{
[SwiftObjct classMethod];
NSLog(@"oc class method");
}
此時(shí)還會報(bào)錯(cuò)Use of undeclared identifier 'SwiftObjct'
,這個(gè)地方就還需要導(dǎo)入一個(gè)新的文件:
// 名字前綴是工程名
#import "SwiftObjectiveC-Swift.h"
你會發(fā)現(xiàn)葵萎,在工程中搜不到此頭文件导犹,這是因?yàn)檫@個(gè)類時(shí)隱藏的,工程自動(dòng)生成的羡忘,它的作用就是對工程中所有swift類文件進(jìn)行了向Objective-C語言的翻譯谎痢。所以導(dǎo)入這個(gè)頭文件之后,上面的代碼就不會報(bào)剛才的錯(cuò)了卷雕。但是又報(bào)新的錯(cuò)誤了节猿,SwiftObjct類是識別了,但是不識別它的方法和屬性:
這是因?yàn)镾wift4.0以后,暴露給Objective-C類調(diào)用的swift方法和屬性都要在前面加上修飾詞:@objc滨嘱,否則Objective-C類無法找到對應(yīng)的Swift方法和屬性峰鄙。另外需要注意定義后一定要command+B編譯通過一下工程,才能正常在Objective-C文件中調(diào)用swift屬性和方法太雨。
所以對SwiftObjct.swift修改如下:
import UIKit
class SwiftObjct: NSObject
{
@objc var name = "swiftObject"
@objc func instanceMethod( ) -> Void
{
print("swift instance method")
}
@objc class func classMethod( ) -> Void
{
print("swift class method")
}
}
然后command+B編譯過后吟榴,報(bào)錯(cuò)都沒有了,并正常打幽野狻:
swift instance method
2019-08-12 18:06:09.617260+0800 SwiftObjectiveC[19281:400024] oc instance method, swiftObjct.name=swiftObject
swift class method
2019-08-12 18:06:09.617474+0800 SwiftObjectiveC[19281:400024] oc class method
注意:
1吩翻、Swift類中不需要import頭文件,因?yàn)樗鼈兊淖饔糜蚴侨值模?br>
2锥咸、SwiftObjectiveC-Swift.h文件是隱藏的狭瞎,它對工程中所有swift類文件進(jìn)行了向Objective-C語言的翻譯;
3搏予、修改Swift類后一定要command+B編譯通過一下脚作。