__weak
此關鍵字指示編譯器弱導出符號。
可以將 __weak
關鍵字應用於函數和變量聲明以及函數定義。
- 函數和變量聲明
-
對於聲明,此存儲類指定一個 extern 對象聲明,即使不存在,也不會導致鏈接器將未解析的引用作為錯誤處理。
例如:
__weak void f(void); ... f(); // call f weakly
如果從編譯為跳轉或跳轉鏈接指令的代碼中對缺少的弱函數進行引用,則會:
-
將該引用解析為下一條指令的跳轉。這實際上將跳轉變為
NOP
。 -
將該跳轉替換為
NOP
指令。
-
- 函數定義
-
使用
__weak
定義的函數將弱導出其符號。除非將相同名稱的非弱定義函數鏈接到相同映像上,否則弱定義函數的行為與正常定義的函數類似。如果非弱定義函數和弱定義函數位於相同映像中,則會將對弱定義函數的所有調用解析為對非弱函數的調用。如果有多個可用的弱定義,鏈接器將選擇其中的一個弱定義供所有調用使用。如果使用
__weak
聲明函數,但隨后沒有使用__weak
對其進行定義,則此函數與非弱函數的行為相同。
使用 __weak
限定函數和變量聲明以及函數定義時,存在一些限制。
- 函數和變量聲明
-
在同一編譯中,不能既弱使用又非弱使用函數或變量。例如,以下代碼從
g()
和h()
中弱使用f()
:void f(void); void g() { f(); } __weak void f(void); void h() { f(); }
無法從定義某個函數或變量的同一編譯中弱使用該函數或變量。以下代碼從
h()
中非弱使用f()
:__weak void f(void); void h() { f(); } void f() {}
鏈接器不會從庫中加載函數或變量,除非其他編譯非弱使用該函數或變量。如果一直沒有解析引用,則假定其值為
NULL
。但是,如果引用是指從代碼中對位置無關節或缺少的__weak
函數的引用,則未解析的引用不是NULL
。 - 函數定義
-
無法內聯弱定義的函數。
注:此文章為轉載,原文章地址:http://blog.sina.com.cn/s/blog_62d3426b0100g7n6.html