這是一個llvm的指令,很強大,官方文檔中有很多說明,我們這裏記錄我們在開發中可能會遇到的場景和應用
指令格式
__attribute__(相關屬性)
常見場景1 availability 對版本、平臺等情況做說明
在某些時候我們需要對不同的版本和平臺做特別處理,或者API支持,蘋果也有很多這種場景,比如iOS10的系統通知API,UITableView中某些API的限定使用的API_DEPRECATED
等宏定義的背後都是用__attribute__(availability...)
實現的
eg:
我們如果遇到這種場景大可以使用API_XXXX
等宏定義實現我們的需求,但是這裏我們探究一下背後的__attribute__(availability...)
availability的參數如下
introduced
:引進的版本deprecated
:廢棄的版本,還能使用,並沒有移除,而是提醒用戶遷移到其他APIobsoleted
:移除的版本,不能再使用unavailable
:那些平臺不能用message
:額外提示信息,比如遷移到某某API
使用ios
macosx
來指定對應的平臺
實際例子:
效果(實驗環境XCode11.1(11A1027)) iOS 13.1:
系統中的NS_UNAVAILABLE
就是使用的第二種方式實現的.
常見場景2 objc_subclassing_restricted 限定被修飾的類不能被其他類繼承
常見場景3 cleanup
修飾一個變量,在它的作用域結束時可以自動執行一個指定的方法
注意:
- 1,使用
cleanup
的時候約定調用的方法默認必須需要一個參數,這個參數就是被監聽的對象本身 - 2,調用方法用
C
語言,並且形參爲指針的指針 - 3,可以傳遞block
- 4,執行順序如下圖所示
常用場景4 objc_designated_initializer
控制初始化方法必須被調用
在系統提供的宏定義中有這麼一個
#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
被它修飾的初始化方法是強制要求被調用的,換句話說就是,如果你在本類中新寫了其他的初始化方法,你也必須在你的方法中調用此方法,所以我們就可以利用這個修飾來寫一個本類必須的初始化過程,然後提供給其他初始化方法使用,或者讓其直接被調用.可以很好的控制本類對象在初始化過程的必要條件保證.
系統中最常見的應用就是NSObject
中的init
方法
注意事項
事項1: 如果本類有的初始化方法,那麼它必須覆蓋實現父類的objc_designated_initializer
方法,否則會有如下警告
我們按照警告提示覆寫了父類的init
方法,卻出現了另外的警告
大體解釋就是說,因爲你本類有一個objc_designated_initializer
初始化方法,那麼,你就必須用本類的初始化方法,而不能用父類的.
果然,將[super init]
改成[self init]
後不報警告了
對objc_designated_initializer使用總結就是
- 1, 如果本類有
objc_designated_initializer
方法,那麼必須重寫父類的objc_designated_initializer
方法 - 2, 初始化方法如果被
objc_designated_initializer
修飾,那麼在其中必須調用父類的objc_designated_initializer
方法 - 3, 如果本類有
objc_designated_initializer
初始化方法,那麼其他的非objc_designated_initializer
初始化方法必須調用該objc_designated_initializer
方法,不能調用父類的.
常見場景5 unused
消除對象未被使用警告
常見場景6 objc_requires_super
限定方法在重寫時必須先調用父類方法
我們在父類中用objc_requires_super
修飾一個方法
在子類中重寫此方法
我們發現就報了讓我們調用父類方法的警告.
遵循提示,我們在重寫時,調用父類方法,警告消失
常用場景6 objc_runtime_name
控制類在運行時的名稱
標記TestSon
類的運行時名稱爲test_runtime_name
打印
安全加固中的代碼混淆的背後其實就是這個指令,可以防止別人看到我們類真實的名字
總結一下
- 1,
__attribute__
的功能很強大,很靈活,在實際開發中我們可以針對不同的應用場景使用不同的指令讓編譯器滿足我們的需求,提高效率,安全 - 2,
__attribute__
指令有很多,我們介紹的都是日常會用到的,很多沒有介紹道的,可以查看官方文檔,則需而用.