Objective-C內存管理

Objective-C的內存管理實質上就是引用計數(shù)告私。

從前是手動引用計數(shù)(MRC)馁龟,現(xiàn)在是自動引用計數(shù)(ARC)蹋盆。

所謂ARC俭令,就是讓編譯器來進行內存管理后德,現(xiàn)在Xcode默認ARC為有效狀態(tài)。

引用計數(shù):

Objective中抄腔,生成對象時引用計數(shù)為1瓢湃,持有對象引用計數(shù)加一,釋放對象引用計數(shù)減一赫蛇,當對象引用計數(shù)為0時則釋放對象绵患。

在ARC下我們不必關心引用計數(shù)這個概念。但是在MRC下必須清晰引用計數(shù)悟耘,而且要牢記:自己生成的對象自己持有落蝙,非自己生成的對象自己也能持有,不再需要自己持有的對象要釋放暂幼,非自己持有的對象不能釋放筏勒。下面詳細說明:

MRC下:

拿數(shù)組來說,可以使用這兩種方式創(chuàng)建:一種是使用alloc方法旺嬉,另一種是使用array等一系列方法管行。那這兩種方法有什么區(qū)別:

使用alloc方法生成的對象自己持有(持有的概念通過下面的對比會清楚),當不再需要時自己釋放(調用release方法)邪媳,當一個對象的引用計數(shù)為0時不可以再讓變量調用release(非自己持有的對象不能釋放)捐顷。

使用array方法只是取得對象的存在,就是說你可以通過變量訪問這個對象悲酷,但是你不持有它套菜,當你不再需要使用這個對象時你不必調用release方法。你可以對變量調用retain方法來持有對象设易,當你不需要使用對象時調用release方法釋放對象逗柴。

為什么通過array方法獲得的對象有這個特性?

首先說明這不是ARC顿肺。這就要介紹autorelease了戏溺。

我們使用release方法會立即釋放一個對象,而使用autorelease方法會將對象注冊到autoreleasepool中屠尊,具體的步驟如下:

生成NSAutoreleasePool對象旷祸,對不需要被持有的對象調用autorelease方法,廢棄NSAutoreleasePool對象讼昆。當NSAutoreleasePool對象被廢棄時托享,調用過autorelease方法的對象都會被釋放。在iOS開發(fā)中,主線程的NSRunLoop負責對自動釋放池生成廢棄闰围,這里不再贅述赃绊,當然我們可以自己創(chuàng)建自動釋放池,及時廢棄大量占用內存的對象羡榴。需要注意一點:無論哪種類型的變量調用autorelease方法碧查、都是調用NSObject類的autorelease方法,但是NSAutoreleasePool類的autorelease方法已被該類重載校仑,如果NSAutoreleasePool的對象調用autorelease方法時會出現(xiàn)運行時錯誤忠售。

另外使用以下方法、或以以下方法開頭時意味著自己生成的對象自己持有:alloc迄沫、new稻扬、copy、mutablecopy邢滑。

ARC:

在MRC下腐螟,我們通過retain、release困后、autorelease來完成引用計數(shù)(內存管理),在ARC下如何記述如何管理呢衬廷?

所有權限修飾符:

__strong:id和對象類型默認的所有權限修飾符摇予。使用__strong修飾的變量在超出作用域時(或者手動置nil、被賦值等)吗跋,對象被廢棄侧戴。即隨著強引用的失效,引用的對象隨之釋放跌宛。

但是__strong還不夠“strong”酗宋,使用__strong時會出現(xiàn)相互強引用的情況:

相互強引用是內存泄漏的一種情況,對象得不到應有的釋放疆拘。這里詳細說一下相互強引用:

首先要理解這個過程:比如說有個類A蜕猫,它的一個實例a,類A中有一個類B的成員變量bb哎迄,a和a的成員變量bb都被初始化了回右,當a被廢棄時會怎么樣? ? a超出作用域時漱挚,a之前所引用的對象被釋放翔烁,然后變量bb被廢棄,bb之前所引用的對象被釋放旨涝。再來說這種情況蹬屹,有個類A,它的一個實例a,類A中有一個類B的成員變量bb慨默;有個類B秃踩,它的一個實例b,類B中有一個類A的成員變量aa业筏,a和b初始化之后憔杨,分別將a、b賦給aa蒜胖、bb消别。當a和b超出作用域之后,a所引用的對象沒有被釋放台谢,因為aa還在引用它寻狂,b所引用的對象沒有被釋放,因為bb還在引用它朋沮。

__weak提供弱引用蛇券,__weak不持有對象,也就是說對象失去強引用之后無論有多少弱引用都將被釋放樊拓。弱引用還會自動失效處于nil狀態(tài)纠亚。

__unsafe_unretained是不安全的所有權修飾符,使用該修飾符修飾的變量不屬于編譯器的內存管理對象筋夏,當其引用的對象被釋放后不會自動置nil蒂胞。C語言的結構體中,不能含有OC對象条篷,因為C語言沒有方法來管理結構體成員的生存周期骗随,要想加入OC對可以強制轉換為void *或使用__unsafe_unretained修飾符。

__autoreleasing修飾符:

這個修飾符是與MRC下的autorelease方法對應的修飾符赴叹。在ARC下不能使用autorelease方法鸿染,也不能使用NSAutoreleasePool類,但是可以使用@autoreleasepool { ?} 塊來替代NSAutoreleasePool的作用乞巧、使用__autoreleasing修飾符代替調用autorelease方法涨椒。

以下幾種情況非顯示的使用__autoreleaseing:

不是 ?以alloc、new摊欠、copy丢烘、mutableCopy開頭的方法 的返回值的對象 ?默認注冊到autoreleasePool中。

在訪問__weak修飾的變量時些椒,該變量默認被注冊到autoreleasePool中播瞳,因為__weak只持有對象的弱引用,在訪問的過程中很可能對象被廢棄了免糕。這樣可以保證在@autoreleasePool{}塊結束前對象都不會被釋放赢乓。

init方法返回的對象不注冊到autoreleasePool忧侧。(以init開頭的方法必須是實例方法,并且必須返回id類型或者該方法所在類(也可以是其父類或子類)類型的對象牌芋。(-(void)initialiaze方法除外)蚓炬。

要注意只有相同所有權修飾符相同的變量才可以賦值,否則編譯報錯躺屁,如果沒有報錯則說明編譯器自行幫你轉化了肯夏。

最后給出屬性與所有權限修飾符的關系:

assign__unsafe_unretained

copy__strong

retain__strong

strong__strong

unsafe_unretained ? __unsafe_unretained

weak__weak

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市犀暑,隨后出現(xiàn)的幾起案子驯击,更是在濱河造成了極大的恐慌,老刑警劉巖耐亏,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徊都,死亡現(xiàn)場離奇詭異,居然都是意外死亡广辰,警方通過查閱死者的電腦和手機暇矫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來择吊,“玉大人李根,你說我怎么就攤上這事「煞ⅲ” “怎么了朱巨?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長枉长。 經常有香客問我,道長琼讽,這世上最難降的妖魔是什么必峰? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮钻蹬,結果婚禮上吼蚁,老公的妹妹穿的比我還像新娘。我一直安慰自己问欠,他們只是感情好肝匆,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著顺献,像睡著了一般旗国。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上注整,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天能曾,我揣著相機與錄音度硝,去河邊找鬼。 笑死寿冕,一個胖子當著我的面吹牛蕊程,可吹牛的內容都是我干的。 我是一名探鬼主播驼唱,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼藻茂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了玫恳?” 一聲冷哼從身側響起辨赐,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纽窟,沒想到半個月后肖油,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡臂港,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年森枪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片审孽。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡县袱,死狀恐怖,靈堂內的尸體忽然破棺而出佑力,到底是詐尸還是另有隱情式散,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布打颤,位于F島的核電站暴拄,受9級特大地震影響,放射性物質發(fā)生泄漏编饺。R本人自食惡果不足惜乖篷,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望透且。 院中可真熱鬧撕蔼,春花似錦、人聲如沸秽誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锅论。三九已至讼溺,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棍厌,已是汗流浹背肾胯。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工竖席, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人敬肚。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓毕荐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親艳馒。 傳聞我的和親對象是個殘疾皇子憎亚,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容

  • 內存管理的問題# ??先看看下面的幾段代碼,重溫一下使用內存常見的問題弄慰。 ??C語言中內存操作常見錯誤: 內存分配...
    DeanYan閱讀 1,018評論 0 1
  • 內存管理 內存管理原則 自己生成的對象自己持有alloc第美、new、copy陆爽、mutable以及符合以這些關鍵字為前...
    小強七號閱讀 259評論 0 0
  • 一.開篇之初 內存管理解決的問題就是:1)防止野指針的生成(野指針:指向變量的指針還存在什往,但是所指向的內存已經被釋...
    半紙淵閱讀 1,010評論 0 1
  • 提前兩個月?lián)屍保谲囌緩V場外排隊幾個小時上車慌闭,短則幾小時長則幾十個小時回家别威。難道是為了聽七大姑八大姨八卦個人隱私?...
    Russell2016閱讀 386評論 0 0
  • 最近一段時間同學驴剔、朋友邀約的聚會不斷省古,我都婉拒了。不是我不想去丧失,確實不方便豺妓,又不能喝酒,怕掃了大家的興布讹。特別...
    天行健君馬甲閱讀 228評論 0 5