Objective-C 和 Swift 混編項目的小 Tips(一)

本文主要閒聊一些 Objective-C 和 Swift 混編項目帶來的一些潛規則,但願能幫到對此感到疑惑的朋友。下面咱們開始進入主題:objective-c

命名

官方 Guide 上只是簡單敘述(Using Swift with Cocoa and Objective-C),即 Swift 編譯器會在咱們使用 Objective-C 的 API 時自動的將其轉成 Swift 風格的 API(說白了就是會對一些方法名、枚舉名等等作一些有規則的刪減,即重命名)。swift

單例方法命名

在 Swift 中引用 Objective-C 單例時,若是單例方法包含於類名,則會出現編譯錯誤,下面咱們來看幾個例子。bash

Example 1

@interface TXLocationManager : NSObject

+ (instancetype)manager;

@end

複製代碼

TXLoginManager 類有一個單例方法命名爲 manager,在 Swift 中引用 manager 方法時,會出現編譯錯誤:ide

說白了,manager 方法已經廢了。。。ui

Example 2

在 Example 1 的基礎上,咱們把單例方法的命名改一改:spa

@interface TXLocationManager : NSObject

+ (instancetype)shareInstance;

@end

複製代碼

單例方法命名改爲 shareInstance 後,編譯經過了。至此,至少問題已經解決了,如今咱們再簡單看看是什麼緣由?爲什麼 manager 方法沒法引用,而 shareInstance 卻能夠引用呢?3d

Example 3

在 Example 1 的基礎上,把 manager 單例方法名稱改成 shareManager :code

@interface TXLocationManager : NSObject

+ (instancetype)shareManager;

@end

複製代碼

咱們能夠發如今 Swift 中引用時,shareManager 方法名被重命名爲 share :cdn

小結

至此,咱們能夠得出一個簡單的命名潛規則:在 Swift 中引用 Objective-C 單例時,若是單例方法包含於類名,則會出現編譯錯誤,準確的說,應該是若是單例方法的名稱正好是該類名駝峯命名的後綴,那麼在 Swift 中引用該單例方法時,會出現編譯錯誤。對象

爲什麼在 Swift 中引用 Objective-C 類的 API 會出現這種問題呢?官方 Guide 上時這樣描述的:

The Swift compiler automatically imports Objective-C code as conventional Swift code. It imports Objective-C class factory methods as Swift initializers, and Objective-C enumeration cases truncated names.

由於 Swift 編譯器在使用 Objective-C 的代碼時會自動的將其轉成 Swift 風格的代碼,就是會對一些方法名、枚舉名等等作一些有規則的刪減。

There may be edge cases in your code that are not automatically handled. If you need to change the name imported by Swift of an Objective-C method, enumeration case, or option set value, you can use the NS_SWIFT_NAME macro to customize how a declaration is imported.

根據官方 Guide,上述的這種 case 屬於 特殊的狀況。那如何解決這種問題呢,Swift 提供了一個宏,專門處理咱們遇到的這種 case —— NS_SWIFT_NAME

@interface TXLocationManager : NSObject

+ (instancetype)manager NS_SWIFT_NAME(shareInstance());

@end

複製代碼

這樣,manager 該單例方法,當咱們在 Swift 中引用時,會被重命名爲 shareInstance。

let _ = TXLocationManager.shareInstance()

複製代碼

普通方法命名

有時候,咱們在 Swift 中引用 Objective-C 中某個類的 API 時,方法名是可能會被重命名的,下面咱們直接看例子。

類方法

@interface TXLocationManager : NSObject

+ (instancetype)managerWithCoordinateY:(CGFloat)y

// Or
// + (TXLocationManager *)managerWithCoordinateY:(CGFloat)y

@end

複製代碼

當該類的類方法返回自身類型的實例對象時,上述的方法會被重命名。應該這樣引用:

// 方式一:
let _ = TXLocationManager.init(coordinateY: 9)

// 方式二:
let _ = TXLocationManager(coordinateY: 9)

// 錯誤引用方式,編譯失敗
let _ = TXLocationManager.manager(withCoordinateY: 9)

複製代碼

經過上述實踐,咱們能夠發現類方法中的 manager 前綴會被刪掉,並且變成了 Swift 中的 init 方法。若是該類的類方法不返回自身類型的實例對象呢?

@interface TXLocationManager : NSObject

+ (void)managerWithCoordinateY:(CGFloat)y;

// Or
// + (NSObject *)managerWithCoordinateY:(CGFloat)y;
// + (CGFloat)managerWithCoordinateY:(CGFloat)y;

@end

複製代碼

經過實踐能夠發現,在 Swift 中是能夠這樣引用的:

TXLocationManager.manager(withCoordinateY: 9)

複製代碼

這種方式的引用同咱們通常的方法引用是一致的,無異同。

實例方法

實例方法的重命名規則與類方法有點類似,此處就再也不詳述了,感興趣的朋友能夠本身實踐一下。(固然方法的重命名咱們通常均可以經過 NS_SWIFT_NAME 來指定)

參考連接

How to call an Objective-C singleton from Swift?

相關文章
相關標籤/搜索