attribute 的詳解
目錄
- 說明
-
用法與解說
- format
- noreturn
- availbility
- unavailable
- noinline & always_inline
- pure And const
- nothrow
- sentinel
- format_arg
- no_instrument_function
- constructor&destructor
- used
- section
- unused
- deprecated
- weak
- malloc
- alias
- warn_unused_result
- nonnull
- aligned
- packed
- transparent_union
- may_alias
- overloadable
- objc_root_class
- NSObject
- objc_designated_initializer
- visibility
- 更多參考
- 最后的嘮叨
說明
__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
orscanf
的特征绣的,可以使編譯器檢查聲明函數(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ò))
- 通知編譯器函數(shù)從不反回值叠赐,當(dāng)遇到類似函數(shù)還未運(yùn)行到return語句就需要退出來的情況欲账,該屬性可以避免出現(xiàn)錯(cuò)誤信息。(簡(jiǎn)單來說又來這個(gè)定義 就算函數(shù)聲明是有返回值的芭概,但是加了這個(gè)
-
例子
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)惹苗,目前只支持ios
和macos
-
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)毁涉。
- 用于函數(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 給出的建議是:
-
- 語法
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.
- If
- 語法
__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
通常用于修飾全局變量缩功。
- 通常情況下皱碘,編譯器會(huì)將對(duì)象放置于DATA段的data或者bss節(jié)中询一。但是,有時(shí)我們需要將數(shù)據(jù)放置于特殊的節(jié)中癌椿,此時(shí)
- 格式
-
__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ù)
- 告訴編譯器,這個(gè)函數(shù)/屬性可能不被調(diào)用都办,GCC也不會(huì)對(duì)函數(shù)產(chǎn)生警告嫡锌,使用
- 格式
__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(弱別名)。
- 弱引用符的作用和說明:
- 將變量或者函數(shù)定義為弱引用符
- 格式
__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济丘,程序直接崩潰谱秽。
- 這會(huì)導(dǎo)致2個(gè)結(jié)果:
- 所以這個(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ì)生效费就。
- 情況是這樣的钾虐,碰到一個(gè)棘手的問題:我們不確定外部模塊是否提供一個(gè)函數(shù)func噪窘,但是我們不得不用這個(gè)函數(shù),即自己模塊的代碼必須用到func函數(shù):
- 產(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.
- 因?yàn)?char 為1 字節(jié) ,int 為 4 字節(jié)隧饼,short為兩個(gè)字節(jié) 沈堡,所以sizeof(Family) = member3偏移值(member2偏移值(member1偏移值 + sizeof(member1)) + sizeof(member2)) + sizeof(member3);
- 第2個(gè)為什么是 12?
- 因?yàn)槲覀冊(cè)O(shè)置
__attribute__ ((aligned (1)))
但是我們成員最大的是4為猬膨,所以最終結(jié)果還是按照 4來算角撞,所以最終結(jié)果還是 12
- 因?yàn)槲覀冊(cè)O(shè)置
- 第3個(gè)為什么是 16?
- 因?yàn)槲覀冊(cè)O(shè)置
__attribute__ ((aligned (8)))
8 > 4 勃痴,所以最終結(jié)果是按照 8來算谒所,所以最終結(jié)果還是 81 < 10 < 82 說以最終的結(jié)果是 16。
- 因?yàn)槲覀冊(cè)O(shè)置
- 參考
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ò)誤的地方希望指出謝謝肄鸽。
-
format ?
-
noreturn ?
-
availbility ?
-
unavailable ?
-
noinline&always_inline ?
-
pure&const ?
-
nothrow ?
-
sentinel ?
-
format_arg ?
-
no_instrument_function ?
-
constructor&destructor ?
-
used ?
-
section ?
-
unused ?
-
deprecated ?
-
weak ?
-
malloc ?
-
alias ?
-
warn_unused_result ?
-
nonnull ?
-
aligned ?
-
packed ?
-
transparent_union ?
-
may_alias ?
-
overloadable ?
-
objc_root_class ?
-
NSObject ?
-
objc_designated_initializer ?
-
visibility ?
-
參考 ?
-
嘮叨 ?