課堂筆記:
- 只有OC對象才需要進行內存管理的本質原因是OC對象存放在堆里面,非OC對象一般放在棧里面(棧內存會被系統自動回收)
- 當使用alloc、new或者copy創建一個對象時,對象的引用計數器默認就是1
- 僵尸對象:已經被銷毀的對象(不能再使用的對象)
- 野指針:指向僵尸對象(壞內存)的指針,給野指針發消息會報EXC_BAD_ACCESS錯誤
- 空指針:沒有指向儲存空間的指針(里面存的是nil,也就是0),給空指針發消息是沒有任何反應的
- 為了避免野指針錯誤的常見方法:在對象被銷毀之后,將指向對象的指針變為空指針
- 一旦重寫dealloc方法,就必須調用[super dealloc],并且必須放在最后面調用
引用計數器的常見操作
- 給對象發送一條retain消息,可以使引用計數器值+1(retain方法返回對象本身)
- 給對象發送一條release消息,可以使引用計數器值-1
- 給對象發送retainCount消息,可以獲得當前的引用計數器值
注意:release并不代表銷毀/回收對象,僅僅是引用計數器-1
-
要想手動調用retain、release等方法,就必須關閉ARC功能 在build Setting下搜索automatic r就可以
手動管理內存 -
默認情況下,Xcode是不會管僵尸對象的,使用一塊被釋放的內存也不會報錯,為了方便調試,應該開啟僵尸對象監控
僵尸對象監控
@property參數
- 控制set方法的內存管理
1.retain:release舊值,retain新值(OC對象)
2.assign:直接賦值,不做任何內存處理(默認,用于非OC對象類型)
3.copy:release舊值,copy新值(一般用于NSString *) - 控制需不需生成set方法
1.readwrite:同時生成set方法和get方法(默認)
2.readonly:只會生成get方法 - 多線程管理
1.atomic:性能低(默認)
2.nonatomic:性能高
set方法的內存管理
-(void)setCar:(NSString *)car
{
if (car != _car) {
//對當前正在使用的車(舊車)做一次release
[_car release];
//對新車做一次retain操作
_car = [car retain];
}
}```
***
@class和#import的區別
- 作用上的區別:#import會包含引用類的所有信息(內容),包括引用類的變量和方法。@class僅僅是告訴編譯器有這么一個類,具體這個類里面有什么信息,完全不知
- 效率上的區別:如果有上百個頭文件都#import了用一個文件,或者這些文件依次被#import,那么一旦最開始的頭文件稍有改動,后面引用到這個文件的所有類都需要重新編譯一遍,編譯效率非常低。相對來說,使用@class方式就不會出現這個問題了