ARC下所有權修飾符

oc編程中為了處理對象裤纹,可將變量類型定義為id類型或各種對象類型。

所謂對象類型就是指向NSObject這樣的oc類的指針丧没,例如“NSObject *”鹰椒。id類型用于隱藏對象類型的類名部分。相當于C語言中常用的“void *”呕童;

ARC有效時漆际,id類型和對象類型同C語言類型不同,其類型上必須加所有權修飾符夺饲,所有權修飾符一共有四種奸汇。

__strong,

__weak,

__unsafe_unretained,

__autoreleasing

__strong 修飾符


__strong 修飾符是id類型和對象類型默認的所有權修飾符,也就是說往声,以下源代碼中的id變量擂找,實際上被添加了所有權修飾符。

id objc = [[NSObject alloc] init];

id和對象類型在沒有明確指定修飾符的時候浩销,默認添加__strong修飾符贯涎,上面的源碼與以下相同。

id __strong objc = [[NSObject alloc] init];

那么在MRC下它是如何表達的呢慢洋?

id objc = [[NSObject alloc] init];

[objc release];

為了釋放生成并持有的對象塘雳,增加了release方法的代碼陆盘。該源代碼進行的動作同原先ARC的動作完全一樣。

如代碼所示败明,objc在超出它的變量作用域時隘马,即在該變量被廢棄的時候,會釋放它被賦予的對象妻顶。(PS:__strong修飾符不僅只在變量作用域中酸员,在賦值和作為類成員變量上也能夠正確地管理其對象的所有者,感興趣的讀者可以自己嘗試去編寫)盈包。

正如蘋果宣稱的那樣沸呐,通過__strong修飾符,不必再次鍵入retain或者release呢燥,完美的滿足了引用計數(shù)內(nèi)存管理的思考方式。

· 自己生成的對象寓娩,自己所持有叛氨。

· 非自己生成的對象,自己也能持有棘伴。

· 不再需要自己持有的對象時釋放寞埠。

· 非自己持有的對象無法釋放。

__weak修飾符


看起來__strong修飾符完美的解決了內(nèi)存管理問題焊夸,但是僅僅通過__strong修飾符是完全不夠的仁连。這里提到的問題就是“循環(huán)引用”或者“自引用的問題”。如下圖阱穗。

我們也可以通過代碼來演示

@interface Test : NSObject

{

??????? id __strong _obj;

}

- (void)setObject:(id __strong)obj;

@end

@implementation Test

- (void)setObject:(id)obj{

_obj = obj;

}

@end


{

id test0 = [[Test alloc] init];//對象A

id test1 = [[Test alloc] init];//對象B

[test0 setObject:test1];

[test1 setObject:test0];

}

當出了作用域之后饭冬,test0和test1分別釋放,但是持有對象A的強引用變?yōu)閷ο驜的_obj,持有對象B的強引用變?yōu)閷ο驛的_obj,從而造成了內(nèi)存泄露(內(nèi)存空間使用完畢之后未回收)揪阶。

像下面這種情況昌抠,雖然只有一個對象,但是該對象對其自身持有鲁僚,會發(fā)生自引用

id test0 = [[Test alloc] init];

[test0 setObject:test0];

那么我們怎樣才能避免這些情況呢炊苫?就是我們所說的__weak修飾符,提供弱引用冰沙,它不會持有對象侨艾,等對象的持有者不存在時,會自動廢棄weak的對象拓挥,我們來看下面的代碼唠梨。

id __weak objc = [[Test alloc] init];

這段代碼編譯器并不會報錯只是會給個警告。這段代碼將自己生成并持有的對象賦值給了帶有__weak修飾符的變量objc撞叽。即變量objc持有對持有對象的弱引用姻成。因此插龄,為了不以自己持有的狀態(tài)來保存自己生成并持有的對象,生成的對象會被立即釋放科展。我們用下面的代碼解決上面的警告均牢。

id __strong objc = [[Test alloc] init];

id __weak weakObj = objc;

像這樣,__weak修飾符可以避免循環(huán)引用的問題才睹,通過檢查__weak修飾的變量是否為空徘跪,可以判斷被賦值的對象是否已經(jīng)廢棄。(在ios4之前琅攘,我們可以用__unsafe_unretained來代替)垮庐。

__unsafe_unretained修飾符


__unsafe_unretained修飾符,是不安全的所有權修飾符坞琴。盡管ARC的內(nèi)存管理是編譯器的工作哨查,但是賦有這個修飾符的變量不屬于編譯器的內(nèi)存管理對象。這一點讀者需要注意剧辐。

id __unsafe_unretained objc = [[Test alloc] init];

賦有該修飾符的變量和__weak修飾符一樣寒亥,因為自己生成并持有的對象不能繼續(xù)為自己所有,所以生成的對象會被立即釋放荧关。但是他們的區(qū)別是什么呢溉奕?想想為什么我們需要使用到它。比如在ios4以前忍啤。賦值給賦有__unsafe_unretained修飾符變量的對象在使用的時候加勤,如果沒有確保其真實存在,那么應用程序就會崩潰同波。而賦有__weak修飾符的變量則會輸出nil鳄梅。

__autoreleasing修飾符


ARC有效的時候我們是不能使用autorelease方法的,另外参萄,也不能使用NSAutoreleasePool類卫枝,這樣一來,雖然autorelease無法使用讹挎,但是ARC下autorelease功能是有效的校赤。如下代碼

@autoreleasepool {

????? id __autoreleasing obj = [[Test alloc] init];

}

我們可以看到“@autoreleasepool”塊代替了原來的NSAutoreleasePool,__autoreleasing代替了原來的 autorelease方法筒溃,即對象被注冊到了自動釋放池马篮。但是顯示的加__autoreleasing修飾符在ARC似乎沒有那么常見。

取得非自己生成并持有對象時怜奖,雖然可以使用alloc/new/copy/mutableCopy以外的方法來取得對象浑测,但該對象已經(jīng)被注冊到自動釋放池了。這同在MRC時取得調(diào)用了autorelease方法的對象是一樣的。這是由于編譯器會檢查方法名是否以alloc/new/copy/mutableCopy開始迁央,如果不是則自動將返回值的對象注冊到自動釋放池里面掷匠。我們看下面的代碼。

@autoreleasepool {

id __strong obj = [NSMutableArray array];

}

我們可以看到不使用__autoreleasing也能將obj注冊到自動釋放池岖圈,這是為什么呢讹语?原因就像我上面講到的,編譯器會自動的查看方法名是否以alloc/new/copy/mutableCopy開始蜂科。我們可以看看array方法里面做了什么顽决。

+ (id)array{

return [[NSMutableArray alloc] init];

}

當然我們也可以這么寫:

+ (id)array{

id __strong obj = [[NSMutableArray alloc] init];

return obj;

}

我們來分析一下,由于return對象的時候出了變量的作用域导匣,所以該強引用的對象會被釋放才菠,但是作為函數(shù)的返回值,編譯器會自動將其注冊到自動釋放池贡定。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赋访,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子厕氨,更是在濱河造成了極大的恐慌进每,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件命斧,死亡現(xiàn)場離奇詭異,居然都是意外死亡嘱兼,警方通過查閱死者的電腦和手機国葬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芹壕,“玉大人汇四,你說我怎么就攤上這事√哂浚” “怎么了通孽?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長睁壁。 經(jīng)常有香客問我背苦,道長,這世上最難降的妖魔是什么潘明? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任行剂,我火速辦了婚禮,結果婚禮上钳降,老公的妹妹穿的比我還像新娘厚宰。我一直安慰自己,他們只是感情好遂填,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布铲觉。 她就那樣靜靜地躺著澈蝙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撵幽。 梳的紋絲不亂的頭發(fā)上灯荧,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天,我揣著相機與錄音并齐,去河邊找鬼漏麦。 笑死,一個胖子當著我的面吹牛况褪,可吹牛的內(nèi)容都是我干的撕贞。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼测垛,長吁一口氣:“原來是場噩夢啊……” “哼捏膨!你這毒婦竟也來了?” 一聲冷哼從身側響起食侮,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤号涯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后锯七,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體链快,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年眉尸,在試婚紗的時候發(fā)現(xiàn)自己被綠了域蜗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡噪猾,死狀恐怖霉祸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袱蜡,我是刑警寧澤丝蹭,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站坪蚁,受9級特大地震影響奔穿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜迅细,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一巫橄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茵典,春花似錦湘换、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筹我。三九已至,卻和暖如春帆离,著一層夾襖步出監(jiān)牢的瞬間蔬蕊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工哥谷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留岸夯,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓们妥,卻偏偏與公主長得像猜扮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子监婶,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

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

  • 1.1 什么是自動引用計數(shù) 概念:在 LLVM 編譯器中設置 ARC(Automaitc Reference Co...
    __silhouette閱讀 5,122評論 1 17
  • 自動引用計數(shù) 自動引用計數(shù):指內(nèi)存管理中對引用采取自動計數(shù)的技術惑惶。 內(nèi)存管理/引用計數(shù) 持有對象引起引用計數(shù)加...
    南京小伙閱讀 1,308評論 2 3
  • 剛剛從陸地上來煮盼,對于剛剛的天氣,我給個差評带污,因為卸貨的原因空氣中到處漂泊都是灰塵僵控,令人無法呼吸。早晨的陽光明媚令我...
    大皖安利閱讀 271評論 0 0
  • 當自己認真做好或做成一件事情時鱼冀,可能會體會到一中無擬的自豪與驕傲喉祭。最開始努力的時候,可能不會想到有這么好...
    蟬不知雪默閱讀 181評論 0 0
  • 小包總說......結婚證雷绢,只能證明兩個人躺在床上合不合法,卻不能證明理卑,生活里翘紊,兩個人合不合適。有的家庭藐唠,幾根面條...
    登徒浪子_閱讀 380評論 0 0