這些__attribute__的知識你應該知道

最近查看在網(wǎng)上發(fā)現(xiàn)了個有趣的小玩意__attribute__, 也就是 Clang Attributes,這是一個編譯器提供的功能聂儒,能夠讓我向編譯器指定一些特殊的功能,比如

  • attribute((deprecated)):描述一個方法已經(jīng)廢棄硫痰;
  • attribute((objc_requires_super)):描述子類繼承父類的方法時需要調(diào)用 super方法衩婚;
  • attribute((cleanup(...))): 描述一個變量在作用域結束時能夠執(zhí)行指定方法;
  • ......

Clang 編譯器提供了很多的 __attribute__ 功能效斑,下面會介紹一些 Objective-C 中常用的一些功能谅猾。

可以參考相關的文章 NShipsterclang-attributes

__attribute__((deprecated))

描述一個方法鳍悠,表明這是一個被廢棄的方法,如果有地方在調(diào)用坐搔,編譯器會提示一個警告藏研;并且也提供自定義警告信息,格式如下attribute((deprecated("meesage")))

- (void)thisIsADeprecatedMethod __attribute__((deprecated("This is a deprecated message")));

在 Xcode 中概行,我們編寫代碼的時候蠢挡, 編輯器會和 Clang 編譯器的預編譯系統(tǒng)配合,在我們寫代碼的時候凳忙,就在 IDE 中把警告給顯示出來业踏。

1.jpg

__attribute__((objc_boxable))

能夠給 struct 和 union 提供快捷的“包裝”方式。

  1. CGRect涧卵, CGSize勤家, CGPoint, CGVector 能夠使用框架提供的 boxable 快速“包裝”;
  2. 自定義 struct 或 union 類型柳恐,也可以添加 attribute((objc_boxable)) 以支持 boxable 快速“包裝”伐脖。

CGPoint point = {1, 2};                     // x = 1, y = 2
CGRect rect1 = {1, 2, 3, 4};                // x = 1, y = 2, width = 3, height = 4
CGTriangle triange1 = {1, 2, 3, 4, 5, 6};   // a.x = 1, a.y = 2, b.x = 3, b.y = 4, c.x = 5, c.y = 6
// “包裝”需要的數(shù)據(jù)不夠,不夠的數(shù)據(jù)補0
CGSize size = {1};                          // width = 1, height = 0
// “包裝”的 CGRect 中的 CGPoint 需要的數(shù)據(jù)不夠乐设,不夠的數(shù)據(jù)補0
CGRect rect2 = {{1}, {3, 4}};               // x = 1, y = 0, width = 3, height = 4

typedef struct __attribute__((objc_boxable)) {
    CGPoint x;
    CGPoint y;
    CGPoint z;
} CGTriangle;

CGTriangle triange = {1, 2, 3, 4, 5, 6};
// “包裝”的數(shù)據(jù)多了讼庇,最后一條丟掉
CGTriangle triange2 = {1, 2, 3, 4, 5, 6, 7};// a.x = 1, a.y = 2, b.x = 3, b.y = 4, c.x = 5, c.y = 6

這里“包裝”的方式需要注意:

  • 可以采用平鋪,如{1, 2, 3, 4}近尚,也可以采用嵌套蠕啄,如 { {1, 2}, {3, 4} }
  • 如果“包裝”賦值數(shù)據(jù)的個數(shù)比定義的少,則沒有賦值的部分全部為0戈锻,如CGSize size = {1}; // width = 1, height = 0
  • 如果“包裝”賦值數(shù)據(jù)的個數(shù)比定義的多歼跟,則多余的部分丟掉和媳。如CGTriangle triange2 = {1, 2, 3, 4, 5, 6, 7};// a.x = 1, a.y = 2, b.x = 3, b.y = 4, c.x = 5, c.y = 6
2.jpg

__attribute__((objc_subclassing_restricted))

描述一個是一個不能被繼承的類。

如果定義一個 Father 類嘹承,并且使用__attribute__((objc_subclassing_restricted))描述窗价,那么如果一個 Son 類要去繼承于 Father,編輯器會在編譯器的預編譯系統(tǒng)的幫助下叹卷,在 IDE 里面就把錯誤顯示出來撼港。

3.jpg

__attribute__((objc_requires_super))

描述一個子類繼承父類的方法時,需要調(diào)用 super骤竹,否則給出編譯警告帝牡。

如果定義一個 Father 類,里面包含一個 call 方法蒙揣,并且使用__attribute__((objc_requires_super))描述靶溜,那么如果一個 Son 在調(diào)用 call 的時候,需要顯式的調(diào)用[super call]懒震,如果沒有調(diào)用罩息,那么編輯器會在編譯器的預編譯系統(tǒng)的幫助下,在 IDE 里面就把警告顯示出來个扰。

4.jpg

__attribute__((warn_unused_result))

描述一個方法瓷炮,如果此方法有返回值,但是調(diào)用的地方并未使用返回值递宅,編譯器就會提示一個警告娘香。(編輯器在編譯器的預編譯系統(tǒng)的幫助下,也會在 IDE 中顯示警告)

如下面 Hippo 類的 bite 方法办龄,使用了 __attribute__((warn_unused_result)) 進行描述烘绽,在 bite 方法調(diào)用的時候沒有使用返回值,編譯器就就提示了一個警告

5.jpg

__attribute__((cleanup(...)))

修飾一個變量俐填,在它的作用域結束時可以執(zhí)行一個指定的方法安接。

cleanup 是一個用好了就很爽的屬性,詳細內(nèi)容可以查看黑魔法attribute((cleanup))

基本類型變量

如果一個臨時基本類型變量玷禽,在其超出作用域之后赫段,這個變量會直接調(diào)用 cleanup。

8.jpg

對象變量

如果一個臨時變量對象矢赁,在超出其作用域之后糯笙,其臨時變量(變量本身)會被釋放,但是其指向的對象則會根據(jù)他的生命周期來決定是否釋放撩银。也就是說:

  • 如果臨時變量對象给涕,沒有被其他對象持有,那么最后其會先調(diào)用 cleanup,然后再調(diào)用 dealloc 方法
  • 如果臨時變量對象够庙,被其他對象持有了恭应,那么其只會調(diào)用 cleanup,而 dealloc 是不會被調(diào)用的耘眨。(這是因為臨時變量(變量本身)會被釋放昼榛,但是其指向的對象則會根據(jù)他的生命周期來決定是否釋放)

下面兩個例子可以很好的闡述上面兩個觀點:

6.jpg

而下面的 hippo 對象被當前類給持有了,所以 dealloc 是不會調(diào)用的剔难,只會調(diào)用 cleanup胆屿。

7.jpg

總結

__attribute__ 提供了很多的編譯時功能,恰當?shù)倪\用這些功能偶宫,可以使我們的代碼更加靈活非迹。
1.jpg
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纯趋,隨后出現(xiàn)的幾起案子憎兽,更是在濱河造成了極大的恐慌,老刑警劉巖吵冒,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纯命,死亡現(xiàn)場離奇詭異,居然都是意外死亡痹栖,警方通過查閱死者的電腦和手機扎附,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來结耀,“玉大人,你說我怎么就攤上這事匙铡⊥继穑” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵鳖眼,是天一觀的道長黑毅。 經(jīng)常有香客問我,道長钦讳,這世上最難降的妖魔是什么矿瘦? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮愿卒,結果婚禮上缚去,老公的妹妹穿的比我還像新娘。我一直安慰自己琼开,他們只是感情好易结,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般搞动。 火紅的嫁衣襯著肌膚如雪躏精。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天鹦肿,我揣著相機與錄音矗烛,去河邊找鬼。 笑死箩溃,一個胖子當著我的面吹牛瞭吃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碾篡,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼虱而,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了开泽?” 一聲冷哼從身側響起牡拇,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎穆律,沒想到半個月后惠呼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡峦耘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年剔蹋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辅髓。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡泣崩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出洛口,到底是詐尸還是另有隱情矫付,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布第焰,位于F島的核電站买优,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挺举。R本人自食惡果不足惜杀赢,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望湘纵。 院中可真熱鬧脂崔,春花似錦、人聲如沸梧喷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绊困,卻和暖如春文搂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秤朗。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工煤蹭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人取视。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓硝皂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親作谭。 傳聞我的和親對象是個殘疾皇子稽物,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容