<<iOS 與OS X多線程和內(nèi)存管理>>筆記:MRC與引用計數(shù)

注:本文為筆記形式,所以很多都是摘抄的.<<iOS 與OS X多線程和內(nèi)存管理>>書中寫的很棒,簡單易懂,建議各位看官自己去看看.


前言


知其然而不知所以然,一向是開發(fā)人員所忌諱的.其實(shí)對于iOS的多線程和內(nèi)存管理,當(dāng)時學(xué)習(xí)iOS的時候就已經(jīng)學(xué)習(xí)過了相關(guān)技術(shù)了,但是呢,隨著工作的時間加長用的卻是內(nèi)存管理以及多線程越是越來不明白了,正應(yīng)了開頭的那句話,所以到春季這段時間,我都會以<<iOS 與OS X多線程和內(nèi)存管理>>這本書為基礎(chǔ),內(nèi)存管理,block和GCD的使用進(jìn)行講解說明,這一篇我們就說一下關(guān)于iOS中內(nèi)存管理機(jī)制-引用計數(shù).

內(nèi)存管理的基礎(chǔ)概念


我們都知道,內(nèi)存管理分為五個區(qū),分別是棧區(qū),堆區(qū),靜態(tài)區(qū),常量區(qū),代碼區(qū),每個區(qū)都有著自己的特點(diǎn)(具體可查看華山論劍之iOS內(nèi)存,內(nèi)存管理,copy(拷貝)),我們要知道我們內(nèi)存管理的是內(nèi)存中的堆區(qū),在Xcode4.2之前,Object-C采用的是MRC(手動引用計數(shù))機(jī)制,而在其之后,Object-C采用的是ARC(自動引用計數(shù))機(jī)制.雖然我們現(xiàn)在很多時候用不到MRC機(jī)制,但是我們需要在MRC機(jī)制下運(yùn)行代碼了解程序猿在程序中是如何手動進(jìn)行內(nèi)存管理的.


對象的生成妇押、持有、釋放敲霍、廢棄


在<<iOS 與OS X多線程和內(nèi)存管理>>書中對于引用計數(shù)說到了以下的幾個說法.接下面,我們就對這幾個說法進(jìn)行一一的說明.

  • 自己生成的對象,自己持有.
  • 非自己生成的對象,自己也能持有.
  • 不再需要自己持有的對象時釋放.
  • 非自己持有的對象無法釋放.

那么,對象的生成、持有潭袱、釋放锋恬、廢棄這幾種方式在OC中都是如何表現(xiàn)的,看下表我們先大體粗略的了解一下.(這里我們不會相對autorelease方法進(jìn)行詳細(xì)說明,請看本篇autorelease模塊)

對象操作 OC對應(yīng)方法
生成并且持有對象,引用計數(shù)從0變?yōu)? allocnew彤悔、copymutableCopy
持有對象,引用計數(shù)+1 retain方法
釋放對象,引用計數(shù)-1 release方法
廢棄方法 dealloc方法


自己生成的對象,自己持有

使用alloc晕窑、new卵佛、copymutableCopy這幾種方式就說明自己生成的對象,并且自己持有.我們在實(shí)際開發(fā)過程中接觸到alloc疾牲、new比較多,copymutableCopy是的比較少.

alloc方法是我們經(jīng)常用來創(chuàng)建對象的方法,使用alloc方法retainCount(引用計數(shù))為1,并且返回對象的指針.使用示例如下所示.

//obj的引用計數(shù)為1
id obj = [[NSObject alloc]init];

new方法和alloc方法類似,也能生成并且持有對象.并且retainCount(引用計數(shù))為1.示例如下所示.

//obj的引用計數(shù)為1
id obj = [NSObject new];

copymutableCopy這兩個方法都是生成并且持有對象的副本,兩者的不同之處在于copy生成的是不可變的對象,mutableCopy生成的則是可變對象.具體的示例如下所示.

    id obj = [NSObject new];
    
    //copyObj的引用計數(shù)為1
    id copyObj = [obj copy];
    
    //mutableCopyObj的引用計數(shù)為1
    id mutableCopyObj = [obj mutableCopy];


非自己生成的對象,自己也能持有

我們先看下面書中的例子,以alloc阳柔、new舌剂、copymutableCopy等方法之外的方法取得的對象,因為不是自己生成并且持有的,所以自己并不是對象的持有者,(請注意這是MRC環(huán)境下)

id obj = [NSMutableArray array];

上面的代碼中,NSMutableArray對象被賦值給變量obj,但是變量obj卻并沒有持有該對象,我們需要使用retain方法讓obj持有對象.這時候,NSMutableArray的引用計數(shù)為2.如下所示.

[obj retain];

有人會問為什么引用計數(shù)是2,這是因為NSMutableArray對象被創(chuàng)建的時候,引用計數(shù)為1,然后經(jīng)過retain方法操作之后,NSMutableArray對象的引用計數(shù)+1,所以為2.


不在需要自己持有的對象時釋放

當(dāng)我們持有的對象不再需要的時候,我們需要對持有對象進(jìn)行釋放.釋放的方式使用release這個方法實(shí)現(xiàn),這個方法會使對象的引用計數(shù)減一,如果引用計數(shù)為0的話,系統(tǒng)會自己調(diào)用delloc方法來釋放對象.示例如下所示.

NSMutableArray * obj = [NSMutableArray array];
[obj retain];

[obj release];


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

上面一塊我們說到持有的對象,我們有義務(wù)釋放,但是我們不能釋放自己沒有持有的對象,如果自己沒有持有對象而且強(qiáng)行釋放,那么應(yīng)用程序會發(fā)生崩潰.比如,

NSMutableArray * obj = [NSMutableArray array];
[obj retain];

[obj release];
[obj release];


autorelease


在MRC中,autorelease的使用大大的降低了我們代碼的復(fù)雜度和錯誤率,它看起來很像ARC,但是實(shí)際上它類似于C語言的局部變量.這里我們不得不說NSAutoreleasePool這個類,這個類是我們經(jīng)常提到的自動釋放池.我們每一個程序中都存在一個Main函數(shù),這是程序的主入口,其中@autoreleasepool {}就是一個自動釋放池.

NSAutoreleasePool對象類似于C語言的作用域,對象的創(chuàng)建和釋放之間就是作用域.NSAutoreleasePool對象釋放掉之后,它所對應(yīng)的作用域里面的對象也會釋放掉.

接下來,我們看一下autorelease和NSAutoreleasePool對象是如何配合使用的.

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    
    id obj = [[NSObject alloc]init];
    
    [obj autorelease];
    
    [pool drain];

前面,我們說到retainrelease對引用計數(shù)的影響?那么調(diào)用autorelease的對象,它的引用計數(shù)是怎么變化的呢?

對象執(zhí)行autorelease方法時會將對象添加到自動釋放池中 當(dāng)自動釋放池銷毀時自動釋放池中所有對象作release操作 對象執(zhí)行autorelease方法后自身引用計數(shù)器不會改變,而且會返回對象本身.autorelease實(shí)際上只是把對release的調(diào)用延遲了谴忧,對于每一次autorelease系統(tǒng)只是把該對象放入了當(dāng)前的autorelease pool中,當(dāng)該pool被釋放時,該pool中的所有對象會被調(diào)用Release委造。


結(jié)束


關(guān)于MRC以及引用計數(shù)相關(guān)的筆記就只有這么多了,建議各位看官自己去<<iOS 與OS X多線程和內(nèi)存管理>>,最后還是<<iOS 與OS X多線程和內(nèi)存管理>>的pdf版的下載傳送門,各位看官可以自行去參考查看.

<<iOS 與OS X多線程和內(nèi)存管理>>的PDF版?zhèn)魉烷T??



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末昏兆,一起剝皮案震驚了整個濱河市妇穴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腾它,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曲梗,死亡現(xiàn)場離奇詭異,居然都是意外死亡虏两,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門定罢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旁瘫,“玉大人,你說我怎么就攤上這事境蜕◎。” “怎么了粱年?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵台诗,是天一觀的道長。 經(jīng)常有香客問我拉队,道長,這世上最難降的妖魔是什么粱快? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮漫雷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘降盹。我一直安慰自己,他們只是感情好蓄坏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布丑念。 她就那樣靜靜地躺著,像睡著了一般脯倚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挠将,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音乳丰,去河邊找鬼内贮。 笑死,一個胖子當(dāng)著我的面吹牛夜郁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播竞端,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼技俐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起雕擂,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤贱勃,失蹤者是張志新(化名)和其女友劉穎谤逼,沒想到半個月后仇穗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仪缸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宾茂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡跨晴,死狀恐怖片林,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情费封,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布焚鹊,位于F島的核電站,受9級特大地震影響末患,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜璧针,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一渊啰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虽抄,春花似錦、人聲如沸迈窟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽湖员。三九已至,卻和暖如春娘摔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凳寺。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肠缨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓闻书,卻偏偏與公主長得像,于是被迫代替她去往敵國和親魄眉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

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