前提
(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...