__attribute__ 的詳解

attribute 的詳解

目錄

說明

__attribute__ 既熟悉又陌生的關(guān)鍵字科贬,我們很多常用的函數(shù)都有用到這個(gè)關(guān)鍵字(例如:NSLog(),[NSString stringWithFormat:])比默,但是我們平時(shí)開發(fā)過程中又很少直接使用到乳幸。

__attribute__ 是GNU C 的一種體制,本質(zhì)是一個(gè)編譯器的指令润匙,在聲明的時(shí)候可以提供一些屬性,在編譯階段起作用你稚,來做多樣化的錯(cuò)誤檢查和高級(jí)優(yōu)化添坊。可以分別設(shè)置函數(shù)的屬性雇锡,變量屬性和類型屬性逛钻。語法為:attribute(xxx)。

用法與解說

一遮糖、 format[1]

  • 作用

    • format可以給聲明的函數(shù)加上類似printf or scanf的特征绣的,可以使編譯器檢查聲明函數(shù)和函數(shù)實(shí)際調(diào)用參數(shù)之間的格式化字符串是否匹配
  • 語法__attribute__((format(archetype,string-index,first-to-check)))

    • archetype: 格式的類型
    • string-index: 指定傳入函數(shù)的第幾個(gè)參數(shù)是格式化內(nèi)容
    • first-to-check: 指定第一個(gè)可變參數(shù)的位置
  • 例子

    • NSLog()
      • archetype = NSString 表示使用的是NSString風(fēng)格
      • string-index = 1 表示第一個(gè)參數(shù)是格式化字符串
      • first-to-check = 2 第二個(gè)參數(shù)是第一個(gè)可變參數(shù)
    FOUNDATION_EXPORT void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)))
    

noreturn[2]

  • 作用

    • 通知編譯器函數(shù)從不反回值叠赐,當(dāng)遇到類似函數(shù)還未運(yùn)行到return語句就需要退出來的情況欲账,該屬性可以避免出現(xiàn)錯(cuò)誤信息。(簡(jiǎn)單來說又來這個(gè)定義 就算函數(shù)聲明是有返回值的芭概,但是加了這個(gè)noreturn后就算沒有return都不會(huì)報(bào)錯(cuò))
  • 例子

    • exit(int )
    #define __dead2         __attribute__((__noreturn__))
    void     exit(int) __dead2;
    

availbility[3]

  • 作用
    • 告訴編譯器該函數(shù)的生命周期(用于什么平臺(tái)赛不,什么時(shí)候開始,什么時(shí)候廢棄罢洲,什么時(shí)候完全不能使用踢故,那些平臺(tái)不可用,描述信息)
  • 語法 __attribute__((availability(platform,introduced=vesion,deprecated=vesion,obsoleted=version,message=""))) ro ((availability(platform,unavailable)))
    • platform:是指定那個(gè)平臺(tái)惹苗,目前只支持iosmacos
    • introduced :是該方法最初出現(xiàn)時(shí)的版本號(hào)
    • deprecated: 聲明移除的版本號(hào)殿较,當(dāng)超過或者等于該版本號(hào)時(shí)會(huì)出現(xiàn)??
    • obsoleted: 不可用的版本號(hào),當(dāng)超過或者等于該版本號(hào)時(shí)會(huì)出現(xiàn)錯(cuò)誤
    • message: 添加出現(xiàn) 警告 或者 錯(cuò)誤是 的提示語桩蓉,一般用于說明新的替換函數(shù)
  • 例子
    • - (NSString *)filePathForName:(NSString *)name
      • archetype 替換為 ios 說明這個(gè)限制只針對(duì) ios平臺(tái)
      • introduced = 10.1 說明這個(gè)函數(shù)是從ios 10.1開始存在的
      • deprecated = 11.1 說明這個(gè)函數(shù)在ios 11.1開始廢棄
      • obsoleted = 13.0 說明這個(gè)函數(shù)在ios 13.0之后就不能調(diào)用了
      • message = "請(qǐng)使用 - (NSString *)newfilePathForName:(NSString *)name group:(NSString * 提示用戶該函數(shù)的替換方案
    • - (NSString *)newfilePathForName:(NSString *)name
      • archetype 替換為 ios 說明這個(gè)限制只針對(duì) ios平臺(tái)
      • unavailable 為不可使用淋纲, 關(guān)聯(lián) archetype 屬性,則表示該方法不能被 ios平臺(tái)調(diào)用

- (NSString *)filePathForName:(NSString *)name __attribute__((availability(ios,introduced=10.1,deprecated=11.1,obsoleted=13.0,message="請(qǐng)使用 - (NSString *)newfilePathForName:(NSString *)name group:(NSString *)group")));

- (NSString *)newfilePathForName:(NSString *)name __attribute__((availability(ios,unavailable)));

unavailable[4]

  • 作用
    • 告訴編譯器該函數(shù)不可用
  • 語法 __attribute__((unavailable)) or __attribute__((unavailable("說明")))
    • "說明"為說明內(nèi)容
  • 例子
- (NSString *)newfilePathForName:(NSString *)name __attribute__((unavailable("該方法不可用")));

noinline&always_inline[5]

  • 作用
    • 聲明函數(shù)是否新形成內(nèi)聯(lián)函數(shù)
    • ==但是能否形成內(nèi)聯(lián)函數(shù)院究,需要看編譯器對(duì)該函數(shù)定義的具體處理==
  • 語法
    • __attribute__((always_inline)) 內(nèi)聯(lián)函數(shù)
    • __attribute__((noinline)) 不內(nèi)聯(lián)函數(shù)
  • 例子
    • void test_inlineFunc(int i) __attribute__((always_inline))
    • void test_noinlineFunc(int i) __attribute__((noinline))

pure&const[6]

  • 作用
    • pure:屬性表明這個(gè)函數(shù)除了返回值以外沒有任何副作用洽瞬,也就是說它們的返回值只依賴于傳入的參數(shù)和/或全局變量。這種函數(shù)可以通過常見的子表達(dá)式消除和循環(huán)優(yōu)化技術(shù)進(jìn)行優(yōu)化业汰,就像算術(shù)操作符一樣伙窃。
    • const: 屬性表明這個(gè)函數(shù)除了參數(shù)之外不會(huì)對(duì)值進(jìn)行檢查,除了返回值之外也沒有其他副作用样漆。注意为障,一個(gè)有指針類型的參數(shù)同時(shí)檢查指針指向的數(shù)據(jù)的函數(shù),一定不要聲明為 const。同樣的鳍怨,一個(gè)調(diào)用在內(nèi)部非 const 函數(shù)的函數(shù)通常也不能是 const鹅髓。const 函數(shù)返回 void 類型是沒有意義的。
    • 網(wǎng)上比較好的解說 來源于作者:saitjr
      • 用于函數(shù)的返回值僅與入?yún)⒂嘘P(guān)京景,并且函數(shù)狀態(tài)單一窿冯。pure 除了與入?yún)⒂嘘P(guān)外,還與全局變量有關(guān)确徙。這兩個(gè)函數(shù)均屬于函數(shù)式編程醒串,且 const 要比 pure 更為嚴(yán)格一些。對(duì)于這兩個(gè)屬性鄙皇,twitter blog 給出的建議是:
        • 雖然對(duì)于 runtime 來說芜赌,加不加 const 和 pure 關(guān)系不大,但是這對(duì)提高接口可讀性幫助非常大伴逸。
        • 建議給不需要傳入任何參數(shù)的方法加上該屬性缠沈。正因?yàn)椴恍枰雲(yún)ⅲ詿o論何時(shí)返回值都是相同的错蝴,那么完全可以對(duì)返回值進(jìn)行緩存洲愤,之后調(diào)用時(shí),直接返回緩存的結(jié)果即可顷锰。比如柬赐,單例的初始方法(#1)。
        • 如果 Objective-C 某方法用 pure 或 const 修飾了官紫,并且調(diào)用非常頻繁肛宋,那么應(yīng)該考慮將其設(shè)計(jì)為 C 的接口,可優(yōu)化函數(shù)開銷(#2)束世。
        • 即便 pure 與 const 這么好用酝陈,但是一旦用錯(cuò),會(huì)造成 bug 不易發(fā)現(xiàn)毁涉。
  • 語法
    • void test(int i) __attribute__((pure))
    • void test(int i) __attribute__((const))
  • 例子
    • ==因?yàn)楸救艘策€沒理解沉帮,所以先預(yù)留解釋==

nothrow[7]

  • 作用
    • 告訴編譯器該函數(shù)不能拋出錯(cuò)誤
  • 語法
    • __attribute__((nothrow))
  • 例子 - void test(int i) __attribute__((nothrow))

sentinel[8]

  • 作用
    • 告訴編譯器函數(shù)需要nil作為邊界
  • 語法
    • __attribute__((sentinel(index,num)))
      • index: 表示第幾個(gè)參數(shù)需要 nil or NULL
      • num: 表示需要幾個(gè)nil or NULL
  • 例子
    • NSArray 的類方法 :+ (instancetype)arrayWithObjects:(ObjectType)firstObj, ...

      • index = 0 代表第一個(gè)參數(shù)需要nil or NULL作為邊界
      • num = 1 代表需要1個(gè)nil or NULL
          
          #define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0,1)))
          + (instancetype)arrayWithObjects:(ObjectType)firstObj, ... NS_REQUIRES_NIL_TERMINATION;
      
      

format_arg[9]

  • 作用

    • 告訴編譯器 函數(shù)的返回值是字符串類型,并且第幾個(gè)參數(shù)是格式化字符串薪丁。(簡(jiǎn)單的說就是遇西,定義這個(gè)函數(shù)的返回值是字符串,第幾個(gè)參數(shù)也是字符串)
  • 語法

    • __attribute__((format_arg(string-index)))
      • string-index 為參數(shù)的下標(biāo) 從1開始严嗜,不可以超過參數(shù)的數(shù)量
  • 例子

    • NSBundle- (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName
      • string-index = 1 表示第一參數(shù)必須是字符串
    #define NS_FORMAT_ARGUMENT(string-index) __attribute__ ((format_arg(string-index)))
    
    - (NSString *)localizedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName NS_FORMAT_ARGUMENT(1);
    

no_instrument_function[10]

  • 作用
    • If -finstrument-functions is given, profiling function calls will be generated at entry and exit of most user-compiled functions. Functions with this attribute will not be so instrumented.
  • 語法
    • __attribute__((no_instrument_function))
  • 例子

constructor&destructor[11]

  • 作用

    • constructor 定義該屬性的函數(shù)會(huì)在 + Load 函數(shù)之后粱檀, main函數(shù)之前被調(diào)用
    • destructor 定義該屬性的函數(shù)會(huì)在 Exit 之前調(diào)用
  • 格式

    • __attribute__((constructor)) 放在函數(shù)前面
    • __attribute__((destructor)) 放在函數(shù)后面
  • 例子

    
    __attribute__((constructor)) void beforeMain(void){
        NSLog(@"Main之前調(diào)用");
    }
    
    __attribute__((destructor)) void beforeExit(void){
        NSLog(@"exit之前調(diào)用");
    }
    

used[12]

  • 作用
    • used的作用是告訴編譯器,我聲明的這個(gè)符號(hào)是需要保留的漫玄。被used修飾以后茄蚯,意味著即使函數(shù)沒有被引用压彭,在Release下也不會(huì)被優(yōu)化。如果不加這個(gè)修飾渗常,那么Release環(huán)境鏈接器會(huì)去掉沒有被引用的段壮不。具體的描述可以看gun的官方文檔
  • 格式
    • __attribute__((used))
  • 例子
    • void test(int i) __attribute__((used))
    • section 配合好使用放在為被引用的 函數(shù) or 變量被空間優(yōu)化

section[13]

  • 作用
    • 通常情況下皱碘,編譯器會(huì)將對(duì)象放置于DATA段的data或者bss節(jié)中询一。但是,有時(shí)我們需要將數(shù)據(jù)放置于特殊的節(jié)中癌椿,此時(shí)section可以達(dá)到目的健蕊。例如,BeeHive 中就把 module 注冊(cè)數(shù)據(jù)存在 __DATA 數(shù)據(jù)段里面的 “BeehiveMods” section中踢俄。
    • section通常用于修飾全局變量缩功。
  • 格式
    • __attribute__((section(name))) 默認(rèn)使用 DATA段
      • name 為節(jié)點(diǎn)的命名 需要注意命名不能超多 ==16 bytes==
    • __attribute__((section("segname,sectname")))
      • segname 段的名稱 ==長度限制 16 bytes==
      • sectname 節(jié)點(diǎn)名稱 ==長度限制 16 bytes==
  • 例子
    • 定義 段為 _DATA(默認(rèn)段) ,節(jié)點(diǎn)為 _newSection
    void test_func_attr_section (void) __attribute__ ((used,section ("_newSection")));
    void test_func_attr_section (void)
    {
        static int aStatic =0;
        aStatic++;
    }
    
    • 定義 段為 _TEST ,節(jié)點(diǎn)為 _newSection
    void test_func_attr_section (void) __attribute__ ((used,section ("_TEST,_newSection")));
    void test_func_attr_section (void)
    {
        static int aStatic =0;
        aStatic++;
    }
    
  • 參考

unused [14]

  • 作用
    • 告訴編譯器,這個(gè)函數(shù)/屬性可能不被調(diào)用都办,GCC也不會(huì)對(duì)函數(shù)產(chǎn)生警告嫡锌,使用__unused 也可以達(dá)到同樣的效果,用于聲明函數(shù)中沒有被使用到的參數(shù)
  • 格式
    • __attribute__((unused))
  • 例子
    - (void) test __attribute__((unused));
    //or
    int test __attribute__((unused));
    // or
    -(void) test:(NSString *)__unused name;
    
    

deprecated[15]

  • 作用
    • 告訴編譯器該函數(shù)/變量已經(jīng)過期琳钉,并警告
  • 格式
    • __attribute__((deprecated))
    • __attribute__((deprecated(msg)))
      • msg : 警告提示的內(nèi)容
  • 例子
        -(void) oldFunc __attribute__((deprecated));
        //or
        -(void) oldFunc2 __attribute__((deprecated("請(qǐng)使用: - (void) newFunc2");
    

weak[16]

  • 作用
    • 將變量或者函數(shù)定義為弱引用符
      • 弱引用符的作用和說明:
        • 若兩個(gè)或兩個(gè)以上全局符號(hào)(函數(shù)或變量名)名字一樣势木,而其中之一聲明為weak symbol(弱符號(hào)),則這些全局符號(hào)不會(huì)引發(fā)重定義錯(cuò)誤槽卫。鏈接器會(huì)忽略弱符號(hào)跟压,去使用普通的全局符號(hào)來解析所有對(duì)這些符號(hào)的引用胰蝠,但當(dāng)普通的全局符號(hào)不可用時(shí)歼培,鏈接器會(huì)使用弱符號(hào)。當(dāng)有函數(shù)或變量名可能被用戶覆蓋時(shí)茸塞,該函數(shù)或變量名可以聲明為一個(gè)弱符號(hào)躲庄。弱符號(hào)也稱為weak alias(弱別名)。
  • 格式
    • __attribute__((weak))
  • 例子
    • 情況是這樣的钾虐,碰到一個(gè)棘手的問題:我們不確定外部模塊是否提供一個(gè)函數(shù)func噪窘,但是我們不得不用這個(gè)函數(shù),即自己模塊的代碼必須用到func函數(shù):
      extern int func(void);
      ...................
      int a = func();
      if( a > .....)
      {
          ..........
      }
      ............
      
    • 我們不知道func函數(shù)是否被定義了效扫;
      • 這會(huì)導(dǎo)致2個(gè)結(jié)果:
        • 1:外部存在這個(gè)函數(shù)func倔监,并且EXPORT_SYMBOL(func),那么在我自己的模塊使用這個(gè)函數(shù)func菌仁,正確浩习。
        • 2:外部其實(shí)不存在這個(gè)函數(shù),那么我們使用func济丘,程序直接崩潰谱秽。
    • 所以這個(gè)時(shí)候洽蛀,attribute((weak)) 派上了用場(chǎng)。
    • 在自己的模塊中定義:
          int  __attribute__((weak))  func(......)
          {
              return 0;
          }
      
    • 將本模塊的func轉(zhuǎn)成弱符號(hào)類型疟赊,如果遇到強(qiáng)符號(hào)類型(即外部模塊定義了func)郊供,那么我們?cè)诒灸K執(zhí)行的func將會(huì)是外部模塊定義的func。
    • 如果外部模塊沒有定義近哟,那么驮审,將會(huì)調(diào)用這個(gè)弱符號(hào),也就是在本地定義的func吉执,直接返回了一個(gè)1(返回值視具體情況而定)
    • 相當(dāng)于增加了一個(gè)默認(rèn)函數(shù)头岔。
    • 原理:連接器發(fā)現(xiàn)同時(shí)存在弱符號(hào)和強(qiáng)符號(hào),有限選擇強(qiáng)符號(hào)鼠证,如果發(fā)現(xiàn)不存在強(qiáng)符號(hào)峡竣,只存在弱符號(hào),則選擇弱符號(hào)量九。如果都不存在:靜態(tài)鏈接适掰,恭喜,編譯時(shí)報(bào)錯(cuò)荠列,動(dòng)態(tài)鏈接:對(duì)不起类浪,系統(tǒng)無法啟動(dòng)。
    • weak屬性只會(huì)在靜態(tài)庫(.o .a )中生效肌似,動(dòng)態(tài)庫(.so)中不會(huì)生效费就。
  • 產(chǎn)考

malloc [17]

  • 作用
    • 使用該屬性標(biāo)記的函數(shù)返回的塊必須不包含任何指向其他對(duì)象的指針。這樣做的目的是幫助編譯器估計(jì)哪些指針可能會(huì)指向同一個(gè)對(duì)象:這個(gè)屬性告訴GCC川队,它不需要擔(dān)心你的函數(shù)返回的對(duì)象可能包含指向它正在跟蹤的其他對(duì)象的指針力细。
  • 格式
    • __attribute__((malloc))
  • 例子
  • 產(chǎn)考

alias[18]

  • 作用
    • 標(biāo)記該屬性的函數(shù),作為指定函數(shù)的別名
  • 格式
    • __attribute__((alias(source_name))
      • source_name 原函數(shù)或者屬性名稱,(需要主要?jiǎng)e名的參數(shù)固额,返回值定義眠蚂,必須和原來的函數(shù)相匹配)
  • 例子
    • 函數(shù)別名定義例子
    void oldFunc(void)
    {
        printf("%s\n", __FUNCTION__);
    }
    void newFunc(void) __attribute__((alias("oldFunc")));
     
    int main(int argc, char *argv[])
    {
        newFunc(); // calls foo
    }
    /** 程序輸出結(jié)果
     oldFunc
    */
    
    • 變量別名定義
    #include <stdio.h>
    int oldVar = 1;
    extern int newVar __attribute__((alias("oldVar"))); 
    int main(int argc, char *argv[])
    {
        printf("oldVar = %d\n", oldVar); // prints 1
    }
    /** 程序輸出結(jié)果
    newname = 1
    */
    
  • 產(chǎn)考

warn_unused_result[19]

  • 作用
    • 告訴編譯器,該屬性標(biāo)記的函數(shù)的返回值必須被使用斗躏,否則會(huì)發(fā)出警告
  • 格式
    • __attribute__((warn_unused_result))
  • 例子
        - (NSString *) getResuntFunc  __attribute__((warn_unused_result))
    

nonnull[20]

  • 作用
    • 告訴編譯器逝慧,那些參數(shù)不能為NULL ro nil 所以參數(shù)類型必須是指針類型
  • 格式
    • __attribute__((nonnull(index..)))
    • index.. 為參數(shù)下標(biāo) 從1 開始
  • 例子
    - (void) saveWithKey:(NSString *)key value:(id) value defaultValue:(id)defaultValue __attribute__((nonnull(1,2)));
    
    • nonnull(1,2) 標(biāo)識(shí)第一個(gè)和第二個(gè)參數(shù)不能為空

aligned[21]

  • 作用
    • 讓所作用的結(jié)構(gòu)成員對(duì)齊在指定長度自然邊界上。如果結(jié)構(gòu)中有成員的長度大于指定長度啄糙,則按照最大成員的長度來對(duì)齊
  • 格式
    • __attribute__((aligned(length)))
      • length 為指定的長度
  • 例子
    • 不加修飾的情況
    typedef struct
    {
        char  member1;
        int   member2;
        short member3;
    }Family;
    
    //輸出字節(jié):
    NSLog(@"Family size is %zd",sizeof(Family));
    
    
    typedef struct
    {
        char  member1;
        int   member2;
        short member3;
    }__attribute__ ((aligned (1))) Family2;
    
    //輸出字節(jié):
    NSLog(@"Family2 size is %zd",sizeof(Family2));
    
    typedef struct
    {
        char  member1;
        int   member2;
        short member3;
    }__attribute__ ((aligned (8))) Family3;
    
    //輸出字節(jié):
    NSLog(@"Family3 size is %zd",sizeof(Family3));
    
    
    
    • 輸出結(jié)果為:
    2020-08-15 14:41:56.994879+0800 TestOCApp[58956:8462998] Family size is 12
    
    2020-08-15 14:41:56.994879+0800 TestOCApp[58956:8462998] Family2 size is 12
    
    2020-08-15 14:41:56.994879+0800 TestOCApp[58956:8462998] Family3 size is 16
    
    • 第1個(gè)為什么是 12笛臣?
      • 因?yàn)?char 為1 字節(jié) ,int 為 4 字節(jié)隧饼,short為兩個(gè)字節(jié) 沈堡,所以sizeof(Family) = member3偏移值(member2偏移值(member1偏移值 + sizeof(member1)) + sizeof(member2)) + sizeof(member3);
        ==因?yàn)槠浦当仨毷浅蓡T大小的整倍數(shù)== 所以: member1偏移值 = 0 ,member2偏移值 = 4(因?yàn)閕nt是4個(gè)字節(jié)桑李,1不是4的整倍數(shù)踱蛀,所以填充3位變成4) 窿给,member3偏移值 = 9
      • 所以最終就是 sizeof(Family) = 9(4(0+1)+4)+1 => 10 ,==但是結(jié)構(gòu)體大小必須是所有成員大小的整數(shù)倍,也即所有成員大小的公倍數(shù)率拒。== 所以 sizeof(Family) 必須是 4的倍數(shù)崩泡, 所以最終大小是 12.
    • 第2個(gè)為什么是 12?
      • 因?yàn)槲覀冊(cè)O(shè)置__attribute__ ((aligned (1))) 但是我們成員最大的是4為猬膨,所以最終結(jié)果還是按照 4來算角撞,所以最終結(jié)果還是 12
    • 第3個(gè)為什么是 16?
        • 因?yàn)槲覀冊(cè)O(shè)置__attribute__ ((aligned (8))) 8 > 4 勃痴,所以最終結(jié)果是按照 8來算谒所,所以最終結(jié)果還是 81 < 10 < 82 說以最終的結(jié)果是 16。
  • 參考

packed[22]

  • 作用
    • 讓指定的結(jié)構(gòu)結(jié)構(gòu)體按照1字節(jié)對(duì)齊計(jì)算方式與aligned相近沛申,只是全部強(qiáng)制是1的倍數(shù)來計(jì)算
  • 格式
    • __attribute__ ((packed))
  • 例子
    typedef struct
    {
        char  member1; //
        int   member2; //
        char member3;//
    }__attribute__((packed)) Family;
    //輸出字節(jié):
    NSLog(@"Family size is %zd",sizeof(Family));
    
    • 輸出結(jié)果為:
    2020-08-15 14:41:56.994879+0800 TestOCApp[58956:8462998] Family size is 6
    

transparent_union[23]

  • 等待填充

may_alias[24]

  • 待定

overloadable[25]

  • 作用
    • 用于c語言函數(shù),可以定義若干個(gè)函數(shù)名相同劣领,但參數(shù)不同的方法,調(diào)用時(shí)編譯器會(huì)自動(dòng)根據(jù)參數(shù)選擇函數(shù)原型
  • 格式
    • __attribute__((overloadable)) 放置在函數(shù)前面
  • 例子
    __attribute__((overloadable)) void print(NSString *string){
        NSLog(@"%@",string);
    }
    __attribute__((overloadable)) void print(int num){
        NSLog(@"%d",num);
    }
    //調(diào)用
    print(10);
    print(@"哈哈");
    

objc_root_class[26]

  • 作用
    • 放置在類定義前铁材,告訴編譯器尖淘,當(dāng)前類是基類
  • 格式
    • __attribute__((objc_root_class))放置在類定義前
  • 例子
    • 來自系統(tǒng)的NSObject定義
    #define OBJC_ROOT_CLASS __attribute__((objc_root_class))
    
    OBJC_ROOT_CLASS
    @interface NSObject <NSObject> {
        ....
    }
    

NSObject[27]

  • 作用
    • 非OC對(duì)象被修飾后,會(huì)當(dāng)作OC對(duì)象來進(jìn)行內(nèi)存處理
  • 格式
    • __attribute__((NSObject))
  • 例子
    @property (nonatomic,strong) __attribute__((NSObject)) CFDictionaryRef myDictionary;
    
    • myDictionary被修飾后會(huì)當(dāng)作OC對(duì)象來進(jìn)行內(nèi)存處理

objc_designated_initializer[28]

  • 作用
    • 用來修飾類的designated initializer初始化方法著觉,如果修飾的方法里沒有調(diào)用super類的 designated initializer村生,編譯器會(huì)發(fā)出警告。
  • 格式
    • __attribute__((objc_designated_initializer))
  • 例子
    • 來自于系統(tǒng)UIViewController 的代碼片段
    #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
    
    - (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
    
    • 當(dāng)重寫 UIViewController 的- (nullable instancetype)initWithCoder:(NSCoder *)coder 方法是饼丘,如果沒有調(diào)用[super initWithCoder:coder]的話 會(huì)觸發(fā)警告

visibility[29]

  • 作用
    • 用于C語言和C++趁桃,主要作用是定義函數(shù)/屬性的訪問范圍
  • 格式
    • __attribut__((visbility("visbility_type")))
      • visbility_type

更多參考[30]

最后的嘮叨[31]

  • 這帖子是我學(xué)習(xí)過程中結(jié)合自己的理解寫出的,有理解錯(cuò)誤的地方希望指出謝謝肄鸽。

  1. format ?

  2. noreturn ?

  3. availbility ?

  4. unavailable ?

  5. noinline&always_inline ?

  6. pure&const ?

  7. nothrow ?

  8. sentinel ?

  9. format_arg ?

  10. no_instrument_function ?

  11. constructor&destructor ?

  12. used ?

  13. section ?

  14. unused ?

  15. deprecated ?

  16. weak ?

  17. malloc ?

  18. alias ?

  19. warn_unused_result ?

  20. nonnull ?

  21. aligned ?

  22. packed ?

  23. transparent_union ?

  24. may_alias ?

  25. overloadable ?

  26. objc_root_class ?

  27. NSObject ?

  28. objc_designated_initializer ?

  29. visibility ?

  30. 參考 ?

  31. 嘮叨 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卫病,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贴捡,更是在濱河造成了極大的恐慌忽肛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烂斋,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡础废,警方通過查閱死者的電腦和手機(jī)汛骂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來评腺,“玉大人帘瞭,你說我怎么就攤上這事≥锛ィ” “怎么了蝶念?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵抛腕,是天一觀的道長。 經(jīng)常有香客問我媒殉,道長担敌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任廷蓉,我火速辦了婚禮全封,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘桃犬。我一直安慰自己刹悴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般集歇。 火紅的嫁衣襯著肌膚如雪甚淡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天捧请,我揣著相機(jī)與錄音,去河邊找鬼。 笑死钓丰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的每币。 我是一名探鬼主播携丁,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼兰怠!你這毒婦竟也來了梦鉴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤揭保,失蹤者是張志新(化名)和其女友劉穎肥橙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秸侣,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡存筏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了味榛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椭坚。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖搏色,靈堂內(nèi)的尸體忽然破棺而出善茎,到底是詐尸還是另有隱情,我是刑警寧澤频轿,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布垂涯,位于F島的核電站烁焙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏耕赘。R本人自食惡果不足惜骄蝇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鞠苟。 院中可真熱鬧乞榨,春花似錦、人聲如沸当娱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跨细。三九已至鹦倚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冀惭,已是汗流浹背震叙。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留散休,地道東北人媒楼。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像戚丸,于是被迫代替她去往敵國和親划址。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345