Swift&Objective-C混編互調(diào)

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文件

會自動生成一個(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的類

在工程自動生成的類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í)隱藏的,工程自動生成的,它的作用就是對工程中所有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編譯通過一下。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容