iOS-ARC

本文的內(nèi)容包括

一摹察、所有權(quán)修飾符
二、ARC的基本規(guī)則
三弧腥、ARC的實現(xiàn)

ARC中仍然是通過引用計數(shù)來管理內(nèi)存,這個本質(zhì)沒有變桥帆。只是医增,不需要我們手動的寫代碼去管理內(nèi)存了,編譯器自動幫助我們管理“引用計數(shù)”相關(guān)的部分老虫。那么ARC是通過什么方式來幫我們管理內(nèi)存的呢叶骨?

ARC是通過編譯期運行期兩部分來處理的:

  • 編譯期,編譯器不是通過添加retain/release/autorelease這些方法张遭,而是會直接調(diào)用更底層的C語言函數(shù)(如objc_retain)邓萨。
  • 運行期,ARC也包含運行期組件菊卷。比如缔恳,某些類方法返回對象前,為其執(zhí)行了autorelease操作洁闰,而大多數(shù)情況歉甚,我們會對返回的對象保留,比如:_myPerson = [Person personWithName:@"Kobe"];
    那么其實就相當(dāng)于先執(zhí)行了一個autorelease扑眉,然后又retain了一下纸泄。ARC可以在運行期檢測到這一多余的操作,也就是autorelease后緊跟retain腰素。那么會它們兩個會被改為調(diào)用objc_autoreleaseReturnValueobjc_retainAutoreleasedReturnValue聘裁。objc_autoreleaseReturnValue會檢查后邊是否緊接著調(diào)用objc_retainAutoreleasedReturnValue,如果是弓千,就不將返回的對象注冊到autoreleasepool中而直接傳遞衡便,省略了autorelasepool注冊,實現(xiàn)了最優(yōu)化洋访。

一镣陕、所有權(quán)修飾符

1. __strong修飾符

如它的名字一樣,__strong表示對對象的強引用姻政。持有強引用的變量在超出其作用域的時候被廢棄呆抑,隨著強引用的失效,引用的對象會隨之釋放汁展。

知識點:

  1. __strong修飾符是id類型和對象類型默認(rèn)的所有權(quán)修飾符鹊碍,所以一般不寫__strong。
  2. __strong和__weak和 __autoreleasing修飾符一樣善镰,可以將附有這些修飾符的自動變量初始化為nil妹萨。

2. __weak(iOS5以上才有,之前用__unsafe_unretained)

如它的名字一樣炫欺,__weak修飾符表示對對象的弱引用。不持有對象熏兄。

知識點:

  1. 可以避免循環(huán)引用品洛。
  2. 變量指向的對象被銷毀了树姨,變量也會自動置空為nil。

3. __unsafe_unretained

如它的名字一樣桥状,它是不安全的所有權(quán)修飾符帽揪。

知識點:

  1. 和__weak一樣表示弱引用,不持有對象辅斟,但不會置nil转晰,這也正是不安全的原因。
id __unsafe_unretained obj1 = nil;
    {
        id obj0 = [[NSObject alloc] init];
        obj1 = obj0;
        NSLog(@"A:%@",obj1);
    }
    NSLog(@"B:%@",obj1);

輸出A和B雖然是一樣的地址士飒,但是此時B處obj1已經(jīng)是野指針了查邢。

4. __autoreleasing

通過給對象附加__autoreleasing修飾符 來替代調(diào)用autorelease方法,把對象注冊到autoreleasepool中酵幕。

具體使用情況扰藕,在這里

二芳撒、規(guī)則

1. 不能使用retain/release/retainCount/autorelease

2. 用@autoreleasepool{}代替NSAutoreleasePool對象

3. 不要顯式的調(diào)用dealloc

多數(shù)情況下在dealloc中刪除已注冊的代理或觀察者邓深。不用書寫[super dealloc],因為ARC已經(jīng)自動處理了笔刹。

4. 必須遵守內(nèi)存管理的方法命名規(guī)則

  1. alloc/new/copy/mutableCopy芥备,以上述名稱開始的方法在返回對象時,必須返回給調(diào)用方所應(yīng)當(dāng)持有的對象舌菜。這在ARC下萌壳,依然沒有變。
  2. ARC下追加了一條命名規(guī)則:
  • init酷师,以init開頭的方法讶凉,必須是實例方法,并且返回對象山孔,類型應(yīng)為id或該類的的對象類型懂讯,抑或是超類或子類型。該方法基本上只是對alloc方法返回的對象進(jìn)行初始化操作并返回台颠。
    注:initialize方法并不包含在上述命名規(guī)則里褐望。

5. 對象類型不能作為結(jié)構(gòu)體的成員

因為ARC把內(nèi)存管理的工作分配給了編譯器,所以編譯器必須能夠知道并管理對象的生命周期串前。例如C語言的自動變量(局部變量)可以使用該變量的作用域來管理瘫里。但是對于結(jié)構(gòu)體成員來說,是無法實現(xiàn)的荡碾。

6. 顯式轉(zhuǎn)換id和void*

id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;

但是谨读,__bridge安全性與__unsafe_unretained類似,甚至更低坛吁。很容易造成野指針導(dǎo)致崩潰劳殖。
__bridge還有另外兩種轉(zhuǎn)換铐尚,__bridge_retained和__bridge_transfer

  1. Core Foundation 對象類型不在 ARC 管理范疇內(nèi),需要自己管理.
  2. __bridge只做類型轉(zhuǎn)換哆姻,但是不修改對象(內(nèi)存)管理權(quán)宣增,原來是ARC管理的還用ARC,原來MRC管理的繼續(xù)用MRC
  3. __bridge_retained(也可以使用CFBridgingRetain)將Objective-C的對象轉(zhuǎn)換為Core Foundation的對象矛缨,同時將對象(內(nèi)存)的管理權(quán)交給我們爹脾,后續(xù)需要使用CFRelease或者相關(guān)方法來釋放對象;
  4. __bridge_transfer(也可以使用CFBridgingRelease)將Core Foundation的對象轉(zhuǎn)換為Objective-C的對象箕昭,同時將對象(內(nèi)存)的管理權(quán)交給ARC灵妨。

5. 不能使用NSAllocateObject/NSDeallocObject

6. 不能使用區(qū)域(NSZone)

三、ARC的實現(xiàn)

1. __strong實現(xiàn)

賦值給附有__strong修飾符的變量在實際的程序中是怎樣運行的呢盟广?

{
       id __strong obj = [[NSObject alloc] init];
   }

編譯器在超出作用域時自動插入了release闷串。

{
        id __strong obj = [NSMutableArray array];
    }

執(zhí)行,alloc/new/copy/mutableCopy之外的方法筋量,如array類方法:
像代碼這樣烹吵,返回注冊到autoreleasepool中對象的方法使用了objc_autoreleaseReturnValue,如果其后緊接著調(diào)用objc_retainAutoreleasedReturnValue()桨武,那么就不將返回的對象注冊的autoreleasepool中而直接傳遞肋拔。通過這兩個方法,優(yōu)化了程序運行呀酸。

2.__weak的實現(xiàn)

id __strong obj = [[NSObject alloc]init];
id __weak obj1 = obj;

objc_initWeak函數(shù)中的weak_register_no_lock()把賦值對象obj的地址作為鍵值凉蜂,通過哈希查找找到weak弱引用表中對應(yīng)的數(shù)組,將附有__weak修飾符變量的指針添加到數(shù)組中性誉。如果沒有找到數(shù)組窿吩,表示是第一個weak指針,則新建一個數(shù)組错览。

對象在被廢棄時dealloc方法中會調(diào)用object_dispose函數(shù)纫雁,該方法內(nèi)部會通過調(diào)用weak_clear_no_lock()

  1. 通過哈希查找從weak表中獲取廢棄對象地址作為鍵值的記錄是一個數(shù)組
  2. 將包含在數(shù)組中的所有附有__weak修飾符的變量地址倾哺,遍歷數(shù)組賦值為nil轧邪。
  3. 從weak表中刪除該記錄。
  4. 從weak表中刪除該鍵值羞海。

所以忌愚,如果大量使用__weak修飾符的變量,則會消耗相應(yīng)的cpu資源却邓。良策是只在需要避免循環(huán)引用的時候使用__weak硕糊。

3. __autoreleasing修飾符的實現(xiàn)

objc_autorelease

4. 引用計數(shù)

可以通過_objc_rootRetainCount(obj)來獲取對象的引用計數(shù)值。但實際上并不能完全信任該函數(shù)取得的值。對于已經(jīng)釋放的對象以及不正確的對象地址癌幕,有時也返回1衙耕。另外昧穿,在多線程中使用它勺远,因為存在競態(tài)條件的問題,所以取得的數(shù)值也不一定完全可信时鸵。當(dāng)然它在調(diào)試中還是比較有用的胶逢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市饰潜,隨后出現(xiàn)的幾起案子初坠,更是在濱河造成了極大的恐慌,老刑警劉巖彭雾,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碟刺,死亡現(xiàn)場離奇詭異,居然都是意外死亡薯酝,警方通過查閱死者的電腦和手機半沽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吴菠,“玉大人者填,你說我怎么就攤上這事∽隹” “怎么了占哟?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長酿矢。 經(jīng)常有香客問我榨乎,道長,這世上最難降的妖魔是什么瘫筐? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任蜜暑,我火速辦了婚禮,結(jié)果婚禮上严肪,老公的妹妹穿的比我還像新娘史煎。我一直安慰自己,他們只是感情好驳糯,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布篇梭。 她就那樣靜靜地躺著,像睡著了一般酝枢。 火紅的嫁衣襯著肌膚如雪恬偷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天帘睦,我揣著相機與錄音袍患,去河邊找鬼坦康。 笑死,一個胖子當(dāng)著我的面吹牛诡延,可吹牛的內(nèi)容都是我干的滞欠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼肆良,長吁一口氣:“原來是場噩夢啊……” “哼筛璧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惹恃,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夭谤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后巫糙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朗儒,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年参淹,在試婚紗的時候發(fā)現(xiàn)自己被綠了醉锄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡承二,死狀恐怖榆鼠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亥鸠,我是刑警寧澤妆够,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站负蚊,受9級特大地震影響神妹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜家妆,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一鸵荠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伤极,春花似錦蛹找、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至当编,卻和暖如春届慈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工金顿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留臊泌,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓揍拆,卻偏偏與公主長得像渠概,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子礁凡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

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