iOS記憶體管理

2021-06-20 07:04:24 字數 2977 閱讀 1330

前提

(1). 以下是針對cocoa物件,不包括core foundation

(2). cocoa物件都是用引用計數來跟蹤物件的記憶體使用情況的。

(3). 在子類裡面父類先初始化和後釋放的原則。自己想下為什麼

棧空間和堆空間的區別。

我們說的記憶體管理都是基於堆空間的,因為函式內的棧空間是由編譯器自己控制的。 

關於core foundation的記憶體管理,在下下一次介紹。

記憶體管理主要是解決以下兩個問題:

(1). 記憶體洩漏,記憶體洩漏就是不再使用的物件記憶體沒有及時釋放,導致程式記憶體使用過量,可能影響程式的效率,嚴重過量時可能導致程式被ios系統終止。

(2). 釋放或者重寫正在使用的資料。引發記憶體損壞,會讓程式崩潰或者損壞

ios記憶體管理模型分為mrr(

manual retain-release ) 和 arc(

automatic reference counting ) 

mrr (手動retain和release)

你需要自己控制你擁有的物件的記憶體的分配和釋放。

記憶體管理基本原則

(1).  你擁有你建立的任何物件(以下名稱開頭的方法,alloc,copy,retain,mutablecopy,new等)

(2).  你擁有你retain的物件

(3).  你必須釋放你擁有的不再需要使用的物件(release)

(4).  你不能釋放不是你擁有的物件。 

exp.

- (nsstring

*)fullnameone

- (nsstring

*)fullnametwo

- (nsstring

*)fullnamethree

以上第一種和第二種沒有問題,第三種存在記憶體洩漏的可能,因為呼叫fullname的人並不知道返回的string使用完了還自己手動需要釋放。

為什麼第二種方式沒有alloc,呼叫alloc和沒有呼叫alloc有什麼區別?讀者仔細想下。

使用accessor方法來簡化記憶體管理

@inte***ce

memory : 

nsobject

@property

(nonatomic

, strong

) nsstring

*username;

@property

(nonatomic

, weak

) iboutlet uilabel

*usernamedisplayarea;

@end

#import 

「memory.h"

@implementation

memory

@synthesize

username = 

_username

;@synthesize

usernamedisplayarea = _

usernamedisplayarea;

@end;

以上**有幾個地方需要,1. strong和weak 2. 

@synthesize

username = 

_username

;的含義。username是屬性名,而_username是你成員變數的名字。使用時,self.username實際是呼叫你的屬性username的getter方法,而_username僅僅就是在使用你的成員變數。

tip:

不要在init和dealloc種使用accessor方法,原因:因為在init時候,你的物件還沒有構造完成,所以不能使用當前沒有構造完成的物件,會有不確定的時候發生。

弱引用用得最普遍的是iboutlet,所有的iboutlet都是交給了storyboard和xib檔案進行管理的。 

在mrr中,如何手寫setter方法?

- (void)setusername:(nsstring *)newusername

有兩個點需要注意:

第一,如果屬性是bool型別,那麼getter方法的名字應該是is***,其他情況都是***

第二,setter方法,注意看上面這個setter方法。為什麼不需要判斷username是不是空呢?因為在oc中,傳送訊息給nil是沒有問題的,不會發生任何事情。

以下**有個小tip:

- (nsstring

*)getcurrentusername:(person *)person

tips:

如果傳送訊息給乙個已經被釋放的物件,程式會崩潰。

避免釋放你正在使用的物件,需要注意以下兩個情況

1. 當乙個物件從乙個基礎的集合中釋放時

2. 當物件的父物件被釋放時 

autorelease 是延遲傳送release訊息給你的物件。最近一層的autorelease pool釋放時,對應的release訊息被傳送。

autorelease pool 的問題,在arc中已經被@autoreleasepool{} blocks取代了。

autorelease 解決了以下幾個問題: 

autorelease pool降低了應用程式的peak memory footprint,需要使用autorelease pool來管理產生的執行緒,因為執行緒保持自己的棧空間。

為避免過高的footprint,我們可以在分配適當量的臨時變數後,drain掉pool。

- (void

)autoreleasepooltest

}[pool 

drain];}

arc 自動引用計數

取消了顯示的retain和release,autorelease等,編譯器在編譯階段自動插入了retain和release這些語句。

arc中引入了弱引用(weak)。弱引用在物件還擁有強引用前能使用引用的物件。

弱引用主要是為了解決retain cycle

問題。迴圈引用的問題,物件之間相互擁有。

cocoa建立了乙個約定,父物件必須保持對子物件的強引用,子物件必須保持對父物件的弱引用

ios記憶體管理

引用計數 每個物件有乙個與之相關的整數,稱作 引用計數器 或者 保留計數器 當某段 需要訪問乙個物件時,該段 會將物件的保留計數器 1,表示需要訪問這個物件 當結束對該物件的訪問時,保留計數器 1,表示它不在訪問該物件 當保留計數器為0時,物件被銷毀,所佔記憶體被系統收回。當使用new retain...

IOS 記憶體管理

範圍 任何繼承了nsobject的物件,對基本資料型別無效 原理 每個物件內部都儲存了乙個與之相關聯的整數,稱為引用計數器 當使用alloc new或者copy建立乙個物件時,物件的引用計數器被設定為1 給物件傳送一條retain訊息,可以使引用計數器值 1 給物件傳送一條release訊息,可以使...

IOS 記憶體管理

ios記憶體管理一直是頭疼的問題,有時間做些簡單的筆記 使用assign 對基礎資料型別 nsinteger cgfloat 和c 資料型別 int,float,double,char,等等 使用copy 對 nsstring 使用 retain 對其他 nsobject 和其子類 lnonatom...