巧用 LLVM 特性: Objective-C Class Properties 解耦

Lision發表於2018-03-26

前言

Emmmmm... Objective-C Class Properties 早在 WWDC 2016 中就已經公示,給 Objective-C 加入這個特性主要是為了與 Swift 型別屬性相互操作。

官方是這麼說明的:

Interoperate with Swift type properties.

嘛~ 雖然是為了配合 Swift 加入的新特性,不過聊勝於無哈!

Note: 值得一提的是 Objective-C Class Properties 語法特性雖然是 WWDC 2016 加入的,不過由於是 Xcode 8 中 LLVM Compiler 的特性,因此也適用於 iOS 10 之前的部署版本喲~

索引

  • LLVM
  • Objective-C Class Properties
  • 解耦
  • 總結

LLVM

巧用 LLVM 特性: Objective-C Class Properties 解耦

LLVM 官網 對於 LLVM 的定義:

Note: The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.

Emmmmm... 有趣的是,有的文章把 LLVM 強行展開為 "low level virtual machine" 譯為 “低階別虛擬機器”,不過在 LLVM 官網 可以看到官方明示 LLVM 與傳統的虛擬機器沒有一毛錢關係,名稱 "LLVM" 本身不是縮寫,它僅僅是專案的名稱而已~

嘛~ 可能有的同學不能理解為何 LLVM 是一個編譯器工具鏈集合?這就要從 Apple 的編譯器歷史講起咯~

很久很久以前... 算了,我感覺要跑題了(囧),這裡簡單列一下 Apple 採用過的編譯方案吧:

  • GCC
  • LLVM & GCC
  • LLVM Compiler

GCC

GCC, the GNU Compiler Collection 是一套由 GNU 開發的程式語言編譯器,最初作為 GNU 作業系統 的編譯器使用,後面發展成為類 Unix 作業系統以及 Apple Mac OS X 作業系統的標準編譯器。

原本 GCC 僅能處理 C 語言的編譯,不過 GCC 很快擴充套件以支援 C++,之後的 GCC 越發全面,支援 Objective-C,Fortran,Ada,以及 Go 語言。

值得一提的是 GCC 是一套以 GPL 以及 LGPL 許可證鎖發行的 100% 自由軟體,這意味著使用者可以自由地執行,拷貝,分發,學習,修改並改進該軟體

LLVM & GCC

LLVM 我們前面介紹過了,是模組化 & 可重用性編譯器以及工具鏈技術集合。

LLVM 能夠進行程式語言的 編譯期優化、連結優化、線上編譯優化、程式碼生成

LLVM Compiler

前面介紹過 GCC 支援很多語言,系統架構龐大而笨重,而 Apple 大量使用的 Objective-C 在 GCC 中順位(優先順序)較低。此外,GCC 作為一個純粹的編譯系統,在與 IDE 配合方面的表現也很差。

So,Apple 決定從零開始寫 C,C++,Objective-C 的編譯器 Clang。

至此,Apple 徹底與 GCC 了斷。

Objective-C Class Properties

巧用 LLVM 特性: Objective-C Class Properties 解耦

Objective-C Class Properties 作為 Objective-C 新語法特性在 WWDC2016 What's New in LLVM 中公示,表示 Xcode 8 之後可以使用這一新語法特性。

使用方式很簡單:

  • Declared with class flag
  • Accessed with dot syntax
  • Never synthesized
  • Use @dynamic to defer to runtime

Declared with class flag

@interface MyType : NSObject
@property (class) NSString *someString;
@end
複製程式碼

Accessed with dot syntax

NSLog(@"format string: %@", MyType.someString);
複製程式碼

Never synthesized

@implementation MyType
static NSString *_someString = nil;
+ (NSString *)someString { return _someString; }
+ (void)setSomeString:(NSString *)newString { _someString = newString; }
@end
複製程式碼

Use @dynamic to defer to runtime

@implementation MyType
@dynamic (class) someString;
+ (BOOL)resolveClassMethod:(SEL) name {
...
}
@end
複製程式碼

解耦

筆者在做專案元件下沉時,遇到一個問題,正好適用於 Objective-C Class Properties 發揮:將要下沉的元件庫中某系統類 Categroy 引用了業務層某方法。

巧用 LLVM 特性: Objective-C Class Properties 解耦

業務層應該依賴於將要下沉的元件,而元件既然要下沉就不應該再反過來依賴上層業務實現!

按照常規思路,想要把上層業務中被依賴的部分一起隨元件下沉,但是發現被依賴的部分雖然也屬於一個較為基礎的模組,不過此模組現階段不做下沉...

後來經過組內大佬指點,使用 Objective-C Class Properties 解決了這個問題,即將上層業務被依賴的部分化作將要下沉元件依賴方系統類 Categroy 的 Class Properties。

Note: 在 Categroy 中寫 Objective-C Class Properties 需要使用 Runtime 關聯方法。

巧用 LLVM 特性: Objective-C Class Properties 解耦

總結

  • 介紹了 LLVM 順便提到了 Apple 的編譯系統發展簡史。
  • 使用官方 Demo 簡單介紹了 Objective-C Class Properties 語法特性的書寫方式。
  • 提供了一種巧妙使用 Objective-C Class Properties 解耦的思路。

文章寫得比較用心(是我個人的原創文章,轉載請註明 lision.me/),如果發現錯誤會優先在我的 個人部落格 中更新。如果有任何問題歡迎在我的微博 @Lision 聯絡我~

希望我的文章可以為你帶來價值~


補充~ 我建了一個技術交流微信群,想在裡面認識更多的朋友!如果各位同學對文章有什麼疑問或者工作之中遇到一些小問題都可以在群裡找到我或者其他群友交流討論,期待你的加入喲~

巧用 LLVM 特性: Objective-C Class Properties 解耦

Emmmmm..由於微信群人數過百導致不可以掃碼入群,所以請掃描上面的二維碼關注公眾號進群。

相關文章