iOS 的內存管理

一.內存管理的原因

(1)內存溢出 內存不夠用

(2)野指針異常 指針操作了不屬于自己的存儲空間,指針操作已經銷毀的對象

二.內存管理的方式

(1)MRC? 手動管理內存

(2)ARC? 自動管理內存

三.MRC手動管理內存

1.引用計數器

(1)引用計數器表示有多少人正在使用這個對象。

(2)當沒有任何人使用這個對象時, 系統才會回收這個對象, 也就是說當對象的引用計數器為0時,對象占用的內存就會被系統回收。

(3)如果對象的計數器不為0,那么在整個程序運行過程,它占用的內存就不可能被回收(除非整個程序已經退出 )

(4)任何一個對象, 剛生下來的時候, 引用計數器都為1

(5)當使用alloc、new或者copy(MutableCopy)創建一個對象時,對象的引用計數器默認就是1

2.引用計數器的操作

(1)給對象發送一條retain消息,可以使引用計數器值+1(retain方法返回對象本身)

(2)給對象發送一條release消息, 可以使引用計數器值-1

(3)給對象發送retainCount消息, 可以獲得當前的引用計數器值(retainCount有時候會不準確,建議采用delloc方法來驗證是否完全內存釋放)

注意: release并不代表銷毀\回收對象, 僅僅是計數器-1

3.dealloc方法

(1)當一個對象的引用計數器值為0時,這個對象即將被銷毀,其占用的內存被系統回收。

(2)對象即將被銷毀時系統會自動給對象發送一條dealloc消息 (因此, 從dealloc方法有沒有被調用,就可以判斷出對象是否被銷毀)

dealloc方法的重寫:

一般會重寫dealloc方法,在這里釋放相關資源,dealloc就是對象的遺言

一旦重寫了dealloc方法, 就必須調用[super dealloc],并且放在最后面調用

-(void)delloc{

[super delloc];

}

4.使用注意

不能直接調用dealloc方法

一旦對象被回收了, 它占用的內存就不再可用,堅持使用會導致程序崩潰(野指針錯誤).

5.內存管理規則

(1)誰創建誰release :

如果你通過alloc、new或[mutable]copy來創建一個對象,那么你必須調用release或autorelease。

誰retain誰release:

(2)只要你調用了retain,就必須調用一次release

總結:

有加就有減

曾經讓對象的計數器+1,就必須在最后讓對象計數器-1,最后重寫delloc方法來檢查內存是否完全釋放。

6.多對象內存管理

(1)多對象內存管理規則:

只要還有人在用某個對象,那么這個對象就不會被回收

只要你想用這個對象,就讓對象的計數器+1

當你不再使用這個對象時,就讓對象的計數器-1

(2)setter方法內存管理規則:

retain需要使用的對象

release之前的對象

只有傳入的對象和之前的不同才需要release和retain

- (void)setRoom:(Room *)room

{

// 避免過度釋放(判斷私有成員和局部成員是否相等)

if (room != _room)

{

// 對當前正在使用的車(舊車)做一次release

[_room release];

// _room = nil;

// 對新車做一次retain操作

_room = [room retain];

}

}

(3)dealloc方法的內存管理規則

- (void)dealloc

{

// 當人不在了,代表不用房間了

// 對房間做一次release操作

[_room release];

// 這樣寫逼格高一點? self.room = nil;

[super dealloc];

}

7.@property參數

這里寫圖片描述

(1)控制set方法的內存管理

retain : release舊值,retain新值(用于OC對象)

assign : 直接賦值,不做任何內存管理(默認,用于非OC對象類型)

copy : release舊值,copy新值(一般用于NSString *)

(2)控制需不需要生成set方法

readwrite :同時生成set方法和get方法(默認)

readonly :只會生成get方法

(3)多線程管理

atomic :性能低(默認)

nonatomic :性能高(iOS開發中都用這個屬性)

(4)控制set方法和get方法的名稱

setter : 設置set方法的名稱,一定有個冒號:

getter : 設置get方法的名稱

若有bool類型時最好修改getter方法為:(getter = isXXX)

注意: 不同類型的參數可以組合在一起使用

(5)循環引用

當使用@property屬性聲明兩個對象時,如果同時使用retain,會到時相互引用,內存不會釋放,解決辦法是,一個用retain,一個用assign。

8.autoreleasepool 自動釋放池

(1)在iOS程序運行過程中,會創建無數個池子。這些池子都是以棧結構存在(先進后出),當一個對象調用autorelease方法時,會將這個對象放到棧頂的釋放池。

(2)autorelease是一種支持引用計數的內存管理方式,只要給對象發送一條autorelease消息,會將對象放到一個自動釋放池中,當自動釋放池被銷毀時,會對池子里面的所有對象做一次release操作

注意:

這里只是發送release消息,如果當時的引用計數(reference-counted)依然不為0,則該對象依然不會被釋放。

(3)autorelease使用注意事項

并不是放到自動釋放池代碼中,都會自動加入到自動釋放池

在自動釋放池的外部發送autorelease 不會被加入到自動釋放池中

autorelease是一個方法,只有在自動釋 放池中調用才有效。

如果寫了autorelease就不要寫release

只要在自動釋放池中調用autorelease, 就會將對象放入自動釋放池

自動釋放池中不適宜放占用內存比較大的對象

不要連續調用autorelease,同時也不要把大量循環操作放到同一個 @autoreleasepool 之間

@autoreleasepool {

// 創建對象時用autorelease

Person *p? =[ [Person alloc]init]autorelease];

}

// 類方法

+(instancetype)person{

return [[self alloc]init]autorelease]

}

// 類工廠方法

+(instancetype)personWithAge:(int)age

{

return [[[self alloc] initWithAge:age] autorelease];

}

-(void)dealloc

{

NSLog(@"%s", __func__);

[super dealloc];

}

四、ARC 自動引用計數管理內存

1.ARC機制判斷注意點及優點

ARC機制判斷,ARC機制下有幾個明顯的標志:

不允許調用對象的release方法

再重寫父類的dealloc方法時,不能再調用 [super dealloc];

ARC的注意點:

- ARC是編譯器特性,而不是運行時特性

- ARC不是其它語言中的垃圾回收,有著本質區別ARC的

優點:

- 完全消除了手動管理內存的煩瑣

- 基本上能夠避免內存泄露有時還能更加快速,因為編譯器還可以執行某些優化

2.強指針,弱指針

強指針

默認所有指針變量都是強指針

被__strong修飾的指針

Person *p1 = [[Person alloc] init];

__strong? Person *p2 = [[Person alloc] init];

弱指針

被__weak修飾的指針

__weak? Person *p = [[Person alloc] init];

3.ARC下單對象內存管理

(1)局部變量釋放對象隨之被釋放

(2)清空指針對象隨之被釋放

(3)默認清空所有指針都是強指針

弱指針需要明確說明 :

注意: 千萬不要使用弱指針保存新創建的對象

4.ARC下循環引用問題

與MRC一樣,當兩個對象相互引用時,會出現內存泄露的問題,解決辦法是:一個用strong一個用weak。

5.ARC下@property參數

strong: 用于OC對象, 相當于MRC中的retain

weak: 用于OC對象, 相當于MRC中的assign

assign: 用于基本數據類型, 跟MRC中的assign一樣(默認值)

五.如何將MRC轉換為ARC

如何進行ARC和MRC的混合使用:

轉變為非ARC -fno-objc-arc

轉變為ARC的, -f-objc-arc (不常用)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容