從MRC到ARC

int main(int argc, const char * argv[]) {

? ? ? ? @autoreleasepool {

? ? ? ? ? ? ? ? _objc_autoreleasePoolPrint();

? ? ? ? ? ? ? ? id array = [NSArray arrayWithObjects:@"d", nil];

? ? ? ? ? ? ? ? _objc_autoreleasePoolPrint();

? ? ? }

}

輸出如下:

##############

AUTORELEASE POOLS for thread 0x10007d000

1 releases pending.

[0x101800000]??................??PAGE??(hot) (cold)

[0x101800038]??################??POOL 0x101800038

##############


##############

AUTORELEASE POOLS for thread 0x10007d000

2 releases pending.

[0x101800000]??................??PAGE??(hot) (cold)

[0x101800038]??################??POOL 0x101800038

[0x101800040]???????0x100203950??__NSArrayI

##############


1 page和pool的關系丁屎,這里先說下正勒。將對象添加到自動釋放池噪窘,是將對象添加到page中,每一頁page的大小是固定的浊闪。一個自動釋放池中的對象可能很多,需要占據(jù)好幾頁page哎迄,也可能很少谭贪,只占據(jù)一頁page的一段,甚至可能好多page只占據(jù)了一頁令花。這都視自動釋放池中的對象多少而定阻桅。至于pool包含page還是page包含pool,我覺得怎么說都行兼都。

2 通過打印嫂沉,我們看到這里一頁page,pool只占據(jù)這頁page的一小部分扮碧,因為pool里面就一個對象输瓜。而這個自動釋放池是main函數(shù)中的創(chuàng)建的。在自動釋放池作用域(push->pop或{})中芬萍,所有發(fā)送autorelease消息的對象尤揣,統(tǒng)統(tǒng)加入到該釋放池。

3 自動釋放池還可以嵌套柬祠,對象添加自動釋放池添加到其前最后push的自動釋放池北戏。例如

int main(int argc, const char * argv[]) {

@autoreleasepool {

? ? ?_objc_autoreleasePoolPrint();

? ? ? ?@autoreleasepool {

? ? ? ? ? ? ? ?id array = [NSArray arrayWithObjects:@"d", nil];

? ? ? ? ? ? ? ?_objc_autoreleasePoolPrint(); ??

? ? ? ? }

? ? ? _objc_autoreleasePoolPrint();

}

##############

AUTORELEASE POOLS for thread 0x10007d000

1 releases pending.

[0x101800000]??................??PAGE??(hot) (cold)

[0x101800038]??################??POOL 0x101800038

##############

##############

AUTORELEASE POOLS for thread 0x10007d000

3 releases pending.

[0x101800000]??................??PAGE??(hot) (cold)

[0x101800038]??################??POOL 0x101800038

[0x101800040]??################??POOL 0x101800040

[0x101800048]???????0x1002003b0??__NSArrayI

##############

##############

AUTORELEASE POOLS for thread 0x10007d000

1 releases pending.

................??PAGE??(hot) (cold)

[0x101800038]??################??POOL 0x101800038

##############

嵌套的形式,原理后面會在后面詳細講到


4 當然沒有發(fā)送autoreleased消息的對象漫蛔,不會添加到自動釋放池

5 也證明了__autoreleasing修飾符與autorelease的等價嗜愈,因此ARC下,開發(fā)者可以使用該修飾符等價調(diào)用autorelease



說道NSAutoreleasePool莽龟,必然要講到RunLoop蠕嫁。這里先簡單提一下,在即將進入RunLoop時毯盈,創(chuàng)建自動釋放池剃毒,在準備進入休眠時,清空自動釋放池,然后創(chuàng)建新池赘阀。因此在主線程益缠,由于開啟了RunLoop,即使不手動創(chuàng)建自動釋放池基公,也有自動釋放池的存在幅慌,需要添加到自動釋放池的對象也有池可加,如果我們再根據(jù)需要創(chuàng)建自動釋放池轰豆,就類似自動釋放池的嵌套胰伍,我們可以選擇對象所添加的池子,控制release的時機酸休。子線程默認不開啟RunLoop骂租,因此我們需要手動添加自動釋放池。詳細的后面會講到(例如雨席,RunLoop清空和創(chuàng)建的是哪個池子)


手動內(nèi)存管理

簡單來說菩咨,只要遵循以下三點就可以在手動內(nèi)存管理中避免絕大部分的麻煩:

如果需要持有一個對象,那么對其發(fā)送retain

如果之后不再使用該對象陡厘,那么需要對其發(fā)送release(或者autorealse)

每一次對retain,alloc或者new的調(diào)用抽米,需要對應一次release或autorealse調(diào)用


Automatic Reference Counting,自動引用計數(shù)糙置,即ARC云茸,WWDC2011和iOS5所引入。ARC是LLVM 3.0編譯器的一項特性谤饭,使用ARC标捺,解決了iOS開發(fā)者手動內(nèi)存管理的麻煩。

ARC是Objective-C編譯器的特性揉抵,而不是運行時特性或者垃圾回收機制亡容,ARC所做的只不過是在代碼編譯時為你自動在合適的位置插入retain, release或autorelease,就如同之前MRC時你所做的那樣冤今。因此闺兢,至少在效率上ARC機制是不會比MRC弱的,而因為可以在最合適的地方完成引用計數(shù)的維護戏罢,以及部分優(yōu)化屋谭,使用ARC甚至能比MRC取得更高的運行效率。

MRC除了以上關鍵字之外龟糕,不會影響對象的引用計數(shù)桐磁。例如:

Person *p2 = p1; p2指向p1所指向的對象,但是對象的引用計數(shù)沒有改變讲岁,因為沒有出現(xiàn)上述關鍵字

這就是說我擂,我們需要不斷的重復上述關鍵字衬以,很是麻煩。ARC出現(xiàn)了扶踊!


ARC全程Automatic Reference Counting泄鹏,自動引用計數(shù)郎任。

ARC是LLVM 3.0起編譯器的一項特性秧耗,在編譯單位上,可以設置ARC有效無效舶治。例如我們可以設置整個Projiect的(Apple LLVM X.X - Language - Objective C -> Objective-C Automatic Reference Counting - YES)分井,也可以對單個文件可選擇開啟或禁止ARC(Build Phases - Compiler Flags???-fobjc-arc/-fno-objc-arc)


當我們開啟后,我們就不需要像之前那樣霉猛,顯式調(diào)用retain,release和autorelease尺锚。編譯器會在合適的位置替我們插入這些代碼。因此惜浅,還是引用計數(shù)瘫辩,只是內(nèi)存管理變成了編譯器的工作。

在MRC下坛悉,我們通過alloc/retain/copy/release/autorelease來分析引用計數(shù)伐厌,而在ARC下,我們通過強引用來分析引用計數(shù)(依據(jù)的標準不同了)

ARC下裸影,id類型和對象類型必須附加所有權修飾符挣轨。所有權修飾符有四種,__strong轩猩,__weak卷扮,__unsafe_unretained,__autoreleasing均践。id和對象類型在沒有明確指定所有權修飾符時晤锹,默認為__strong

Person *p1 = [[Person alloc] init]; ?等價于 ?Person __strong *p1 = [[Person alloc] init];

__strong修飾符表示對對象的強引用,持有強引用的變量p1在超出其作用域時被廢棄彤委,強引用失效

Person *p2 = p1;

NSLog(@"%d",_objc_rootRetainCount(p1)); //2

此時有兩個強引用

隨著持有強引用的變量超出作用域或者賦值指向其他對象鞭铆,對象的強引用都會隨之改變,引用計數(shù)也隨之改變)

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末葫慎,一起剝皮案震驚了整個濱河市衔彻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偷办,老刑警劉巖艰额,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異椒涯,居然都是意外死亡柄沮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祖搓,“玉大人狱意,你說我怎么就攤上這事≌罚” “怎么了详囤?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镐作。 經(jīng)常有香客問我藏姐,道長,這世上最難降的妖魔是什么该贾? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任羔杨,我火速辦了婚禮,結(jié)果婚禮上杨蛋,老公的妹妹穿的比我還像新娘兜材。我一直安慰自己,他們只是感情好逞力,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布曙寡。 她就那樣靜靜地躺著,像睡著了一般掏击。 火紅的嫁衣襯著肌膚如雪卵皂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天砚亭,我揣著相機與錄音灯变,去河邊找鬼。 笑死捅膘,一個胖子當著我的面吹牛添祸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寻仗,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼刃泌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了署尤?” 一聲冷哼從身側(cè)響起耙替,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎曹体,沒想到半個月后俗扇,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡箕别,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年铜幽,在試婚紗的時候發(fā)現(xiàn)自己被綠了滞谢。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡除抛,死狀恐怖狮杨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情到忽,我是刑警寧澤橄教,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站绘趋,受9級特大地震影響颤陶,放射性物質(zhì)發(fā)生泄漏颗管。R本人自食惡果不足惜陷遮,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望垦江。 院中可真熱鬧帽馋,春花似錦、人聲如沸比吭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衩藤。三九已至吧慢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赏表,已是汗流浹背检诗。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓢剿,地道東北人逢慌。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像间狂,于是被迫代替她去往敵國和親攻泼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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

  • 概述 在iOS中開發(fā)中鉴象,我們或多或少都聽說過內(nèi)存管理忙菠。iOS的內(nèi)存管理一般指的是OC對象的內(nèi)存管理,因為OC對象分...
    DamonMok閱讀 3,999評論 2 20
  • 內(nèi)存管理 簡述OC中內(nèi)存管理機制纺弊。與retain配對使用的方法是dealloc還是release牛欢,為什么?需要與a...
    丶逐漸閱讀 1,964評論 1 16
  • 29.理解引用計數(shù) Objective-C語言使用引用計數(shù)來管理內(nèi)存俭尖,也就是說氢惋,每個對象都有個可以遞增或遞減的計數(shù)...
    Code_Ninja閱讀 1,490評論 1 3
  • 從JAVA轉(zhuǎn)到IOS開發(fā)娜亿,接觸的不知道是多少年前的OC代碼,還是MRC的啥容,結(jié)果就悲劇了曲秉,各種痛苦。然后用MRC寫了...
    Cooperluffy丨路飛閱讀 281評論 0 0
  • 37.cocoa內(nèi)存管理規(guī)則 1)當你使用new熊赖,alloc或copy方法創(chuàng)建一個對象時来屠,該對象的保留計數(shù)器值為1...
    如風家的秘密閱讀 843評論 0 4