標籤:
記憶體管理
範圍: 任何繼承了NSObject的對象 對基礎資料型別 (Elementary Data Type)無效
原理: 每個對象內部都儲存了一個與之相關聯的整數 稱為引用計數器
1.計數器的基本操作
當使用alloc new或者copy建立一個對象時 對象的引用計數器被設定為1
retain: 計數器+1 會返回對象本身
release: 計數器-1 沒有傳回值
retainCount: 擷取當前的計數器值
dealloc: 當一個對象要被回收的時候 就會調用 一定要調用[super dealloc];這句調用要放在最後面
殭屍對象: 所佔用記憶體已經被回收的對象 殭屍對象不能再使用
野指標: 指向殭屍對象(不可用記憶體)的指標 給野指標發送訊息報錯(EXC_BAD_ACCESS)
null 指標: 沒有指向任何東西的指標(儲存的東西是nil NULL 0) 給null 指標發送訊息不會報錯
2.記憶體管理原則
誰建立 誰釋放 如果你通過alloc new或者copy建立一個對象 那麼你必須調用release或autorelease 換句話說 不是你建立的 就不用你去釋放
一般來說 除了alloc new或者copy之外的方法建立的對象都被聲明了autorelease
誰retain 誰release 只要你調用了retain 無論這個對象是如何產生的 你都要調用release
規範: 只要調用了alloc 必須有release 或 autorelease
set方法的實現
/** 基礎資料型別 (Elementary Data Type) 直接複製 **/- (void) setAge : (int) age { _age = age;}/** OC物件類型 **/- (void) setCar : (Car *) car { //先判斷是不是新傳進來的對象 if (car != _car) { //對舊對象做一次release [_car release]; //對新對象做一次retain _car = [car retain]; }}
dealloc方法的實現
//一定要 [super dealloc]; 而且放到最後面//對self (當前) 所擁有的對象做一次release- (void) dealloc { [_car release]; [super dealloc];}
[email protected]參數
@property (參數, 參數 …) int height;
注意同類型的參數不能寫多個
a.set方法記憶體管理相關的參數
retain: release舊值 retain新值(適用於OC物件類型)
assign: 直接賦值(預設 適用於非OC物件類型)
copy: release舊值 copy新值
b.是否要產生set方法
readwrite: 同時產生set和get的聲明 實現(預設)
readonly: 只會產生get 聲明 實現
c.多線程管理
nonatomic: 效能高(一般就用這個)
atomic: 效能低(預設)
d.set 和 get 方法的名稱
setter = : 決定了set方法的名稱, 一定要有個冒號 :
getter = : 決定了get方法的名稱, (一般用在BOOL類型)
4.迴圈retain和@class
迴圈retain
比如A對象retain了B對象 B對象retain了A對象
這樣會導致A對象和B對象永遠無法釋放
解決方案: 當兩端互相引用時 應該一端用retain 一端用assign
@class的作用: 僅僅告訴編譯器 某個名稱是一個類
@class Person; 僅僅告訴編譯器 Person是一個類
在開發中引用一個類的規範
在.h檔案中用@class來聲明類
在.m檔案中用#import來包含類的所有東西
5.autorelease
int main() { @autoreleasepool {// {開始 代表建立了釋放池 Person *p = [[[Person alloc] init] autorelease]; p.age = 10; }// }結束 代表銷毀了釋放池 return 0;}/** autorelease基本用法 **///會將對象放到一個自動釋放池中//當自動釋放池被銷毀時 會對池子裡的所有對象做一次release操作//會返回對象本身//調用完autorelease方法後 對象的計數器值不變/** autorelease的好處 **///不用再關心對象釋放的時間//不用再關心什麼時候調用release/** autorelease的使用注意 **///佔用記憶體較大的對象不要隨便使用autorelease//佔用記憶體較小的對象使用autorelease沒有太大影響/** 錯誤寫法 **///alloc後調用了autorelease 又調用release//連續調用多次autorelease/** 自動釋放池 **///在IOS程式運行過程中 會建立無數個池子 這些池子都是以棧結構存在(先進後出)//當一個對象調用autorelease方法時 就將這個對象放到棧頂的釋放池/** 開發過程中經常寫一些類方法快速建立一個autorelease的對象 建立對象時不要直接使用類名 用self **/
ARC
1.基本簡介
ARC是自iOS 5之後增加的新特性 完全消除了手動管理記憶體的煩瑣 編譯器會自動在適當的地方插入適當的retain release autorelease語句 你不再需要擔心記憶體管理 因為編譯器為你處理了一切
ARC是編譯器特性 而不是IOS運行時特性 不同於其它語言中的垃圾收集器 因此ARC和手動記憶體管理效能是一樣的 有時還能更加快速 因為編譯器還可以執行某些最佳化
2.基本原理
規則: ARC的規則非常簡單 只要還有一個強指標變數指向對象 對象就會保持在記憶體中
強指標: 預設情況下 所有的指標都是強指標 __strong
弱指標: 弱指標指向的對象被回收後 弱指標會自動變為nil指標 不會引發野指標錯誤 __weak
3.使用注意
不能調用release, retain, autorelease, retainCount
可以重寫dealloc, 但是不能調用[super dealloc];
@property的參數
strong: 成員變數是強指標 (適用於OC物件類型)
weak: 成員變數是弱指標 (適用於OC物件類型)
assign: 適用於非OC物件類型
將不使用ARC時用的retain替換成strong
兩端互相引用時: 一端用strong 一端用weak
關閉整個項目的ARC
關閉某個.m檔案的ARC
Objective-C 記憶體管理和ARC