您好,登錄后才能下訂單哦!
你可以在 xcode 里同時使用 Swift 和 Objective-C(以下簡稱OC)來寫代碼,混搭編程的好處很多,比如允許大量代碼的復用,在性能和開發效率之間找到平衡等。
我們建立一個工程時,XCode會詢問我們選擇什么語言進行開發,如果你選擇的是OC,那么當你第一次新建一個swift文件時,開發環境會詢問你是否建立一個 .h 文件。這個 .h 文件命名方式是 "#ProjectName#-Bridging-Header.h" 。你可以讓開發環境幫你創建這個文件,也可以自己建,編譯器只認這個文件名,只要別寫錯就好。
我們稱這個文件叫橋接文件,它的作用是把OC代碼選擇性的暴露給swift,讓swift可以調用這些接口。
暴露的方式是通過import,也就是說,你可以在這個 .h 文件里 import 任何你想要暴露給swift的代碼,然后就可以在 swift 中訪問了。
動手實踐:
打開xcode,創建一個OC工程 HelloWorld
創建一個叫 HelloOC 的 OC 類,實現靜態方法 hello,實現代碼 NSLog("hello, OC.")
創建一個叫 HelloSwift 的 swift 類,繼承NSObject,實現靜態函數 hello(),實現代碼 NSLog("hello, swift.")
這時候 xcode 會彈出詢問是否創建文件 HelloWorld-Bridging-Header.h ,選擇是,如果你點了否,就自己創建一個
在 HelloWorld-Bridging-Header.h 代碼里,加入 #import "HelloOC.h"
在HelloSwift 的 hello 函數里,在 NSLog("hello, swift.") 后追加 HelloOC.hello()
注意,繼承自 NSObject 這點很重要,因為OC所有類都是繼承自 NSObject,而 swift 沒有這個要求,所以如果需要暴露 swift 的類給 OC ,一定必須是 NSObject 的子類才行。
如果編譯成功了,那就說明編譯器允許讓你通過 HelloSwift 調用 HelloOC 的代碼了。
這時候執行程序,會發現輸出終端并沒有打印任何東西。因為程序主體本身并沒有調用 HelloSwift,我們建立的是 OC 工程,所以這時候就需要 OC 來調用 swift代碼了。
當我們建立 HelloSwift 時,xcode 其實做了一些后臺工作,除了詢問你是否建立 "HelloWorld-Bridging-Header.h" 外,它還隱式的創建了一個叫 "HelloWorld-Swift.h" 的頭文件,記住,這個文件是 xcode 隱式創建的,所以不要自己去建立這個文件,很多人查資料發現需要這個頭文件沒看仔細就自己去創建,結果導致各種編譯不通過。
這個 HelloWorld-Swift 文件從文件到代碼都是 xocode 動態生成的,你不需要編輯它,如果感興趣里面到底寫了什么,你可以通過 import 這個文件,Jump To Definition 的方式一探究竟。
當你需要暴露 swift 的類給 OC 調用時,你不需要通過任何逐個 import 的方式,你只要 import "HelloWorld-Swift.h" 即可。
嘗試步驟如下:
在 ViewController.m 文件中,引入頭文件 #import "HelloWorld-Swift.h"
在 ViewDidLoad 方法的實現中,調用 [HelloSwift hello];
這時候編譯,執行,工程打印日志輸出為:
Hello, Swift.
Hello, OC.
開發項目經常要引用第三方框架,在 swift 中,引用這些框架是非常簡單的,只要在 HelloWorld-Bridging-Header.h 中用 @import 語句包含該框架即可。不管該框架是用什么 swift 還是 OC 寫的,又或者是混合編寫,用法都一樣。
而如果是用 OC 引用這些框架的話,標準做法應該是:
在 .m 文件中,用 @import 語句引用該框架
在 .h 文件中,如果需要在接口中聲明對應的類,則應該用 @class 做前置聲明,用這樣的做法來規避循環引用問題。
舉例 HelloWorld 項目來說,當我們要在 HelloSwift.swift 中引用一個 SwiftFrameWork 框架時,正確的做法是:
在 HelloWorld-Bridging-Header.h 中加入 @import SwiftFrameWork;
在 HelloSwift.swift 中自由調用 SwiftFrameWork 的類。
而如果要在 HelloOC.h 和 HelloOC.m 中這么做,則標準做法應該是:
在 HelloOC.m 中,通過 @import SwiftFrameWork;
在 HelloOC.h 中,如果有需要引用到的 SwiftFrameWork 框架中的類,用前置聲明的方法解決,比如如果需要引用類 ClassA,則可以在引用前聲明 @class ClassA;
如果需要在 HelloOC.h 中引用到 HelloSwift 類,也應該遵循步驟 2 的做法。
對于swift 的 protocol,也可以暴露給 OC 調用,但是需要做一些額外的工作,需要針對要暴露的 swift protocol 添加 @objc 聲明,并且對于 optional 函數也要追加 @objc @optional
在 HelloSwift.swift 追加協議代碼:
// 因為這個 protocol 要暴露給 OC 用,所以用 @objc 聲明 @objc protocol HelloProtocol { // 這是一個普通的swift協議函數 func protocolFunction() // 這是個 optional 函數,需要在前面追加 @objc 聲明 @objc optional func optionalProtocolFunction() }
一旦完成了以上操作,OC類即可聲明和實現對應的協議函數為其他類提供回調實現。
swift 和 OC 之間的錯誤碼共享方案很簡單,就是簡單的命名映射技術,在 swift 中定義錯誤碼如下:
@objc public enum CustomError: Int, Error { case a, b, c }
則 xcode 會在 HelloWorld-Swift.h 中聲明對應的面向 OC 的錯誤碼:
typedef SWIFT_ENUM(NSInteger, CustomError) { CustomErrorA = 0, CustomErrorB = 1, CustomErrorC = 2, }; static NSString * _Nonnull const CustomErrorDomain = @"HelloWorld.CustomError";
命名映射的規則比較簡單明了,Enum 類型名不變,實例的名稱通過大駱駝命名法進行拼接。
HelloOC.h
HelloOC.m
HelloSwift.swift
ViewController.m
蘋果為保證 swift 和 OC 順利交互,做了大量嚴謹的工作,這里就不一一說明了,畢竟道理大同小異,在需要的時候查閱文檔就可以了,類似需要查閱的知識點有:
用 NS_REFINED_FOR_SWIFT 宏重定義 OC 接口
手動為 swift 類指定一個映射名給 OC 調用(通過 @objc)
通過 NS_SWIFT_NAME 指定 swift 自定義名稱
...
Using Swift with Cocoa and Objective-C (Swift 4)
author: Madaxin
email: madaxin@outlook.com
qq group: 527628370
home: madaxin.com
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。