1、retain、release
- retain方法給對象的引用計數器+1
- release方法給對象的引用計數器-1
- retain方法會返回對象自己,release方法沒有返回值
- dealloc方法
- 當一個對象要被回收的時候會被調用
- 重寫的時候,必定要調用[super dealloc]方法,這句調用必定要放到最後面
- 空指針
- OC中沒有空指針異常
- 沒有指向任何東西的指針(存儲的東西是nil、NULL、0),給空指針發送消息不會報錯
- 野指針
- 指向殭屍對象(不可用的內存)的指針,給野指針發送消息會報錯(EXC_BAD_ACCESS)
- 殭屍對象
2、retain、release使用注意
- 誰retain,誰release
- 只要你調用了retain,不管這個對象是如何生成的,你都要調用release
- 善始善終,有加就有減
- 曾經讓對象的計數器+1,就必須在最後讓對象計數器-1
- 若是你經過alloc、new或[mutable]copy來建立一個對象,那麼你必須調用release或autorelease
- 你想使用某個對象,就應該讓對象的計數器+1(讓對象作一次retain操做)
- 當你不想在使用某個對象時,咱們就該讓對象的計數器-1(讓對象作一次release操做)
- 誰retain,誰就release
- 誰alloc,誰就release
3、set方法和dealloc的內存管理
- 只要調用alloc,必須有release(autorelease)
- set方法代碼規範
- (void)setCar:(Car *)car
{
//1.先判斷是否是新傳進來對象
if(car != _car){
//2.對舊對象作一次release -1
[_car release];
//3.對新對象作一次retain +1
_car = [car retain];
}
}
- dealloc方法代碼規範
- 必定要[super dealloc],並且放到最後面
- 對當前對象(self)所擁有的其餘對象作一次release
- (void)dealloc { /* _speed //直接訪問成員變量 self -> _speed //直接訪問成員變量 self.speed //get方法 [self speed] //get方法 */ NSLog(@"速度爲%d的Car對象被回收了",_speed); [super dealloc]; }
4、@property
- 經過@property能夠自動生成帶內存管理的setter方法
- 下面時不帶參數聲明
@property(retain) Book *book;
- 聲明事後,須要到dealloc方法中去release須要release的成員變量
- @property的參數
- set方法內存管理相關的參數
- retain:release舊址,retain新值(適用於OC對象類型)
- assign:直接複製,默認的,能夠不寫(適用於非OC對象類型)
- copy: release舊值,copy新值
- 是否要生成get方法
- readonly:只生成getter方法的聲明、實現
- readwrite:同時生成setter和getter的聲明、實現(默認的)
- 多線程管理
- nonatomic :性能高(通常就用這個)
- atomic :性能低(默認)
- setter和getter的名稱(通常用到BOOL類型)
- getter:設置getter的方法名稱
- setter:設置setter的方法名稱,必須帶冒號:
- 返回BOOL類型的方法名通常以is開頭
@property (getter = isRich) BOOL rich;
5、循環引用
- @class的做用,僅僅告訴編譯器,某個名稱是一個類
- @class Person;
- 開發中引用一個類的規範
- 在.h文件中用@class來聲明類
- 在.m文件中用#import來包含類的全部東西
- @class和#import的區別
- #import方式會包含被引用類的全部信息,包括被引用類的變量和方法;@class方式只是告訴編譯器在A.h文件中 B *b 只是類的聲明,具體這個類裏有什麼信息,這裏不須要知道,等實現文件中真正要用到時,纔會真正去查看B類中信息
- 若是有上百個頭文件都#import了同一個文件,或者這些文件依次被#improt,那麼一旦最開始的頭文件稍有改動,後面引用到這個文件的全部類都須要從新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了
- 在.m實現文件中,若是須要引用到被引用類的實體變量或者方法時,還須要使用#import方式引入被引用類
- 兩端循環引用解決方案
- 一端@property用retain
- 一端@property用assign
6、autorelease
- autorelease的基本用法
- 會講對象放到一個自動釋放池中
- 當自動釋放池被銷燬時,會對池子裏面的全部對象作一次release操做
- 會返回對象自己
- 調用完autorelease方法後,對象的計數器不變
- autorelease的好處
- 不用再關心對象釋放的時間
- 不用再關心何時調用release方法
- autorelease的使用注意
- 佔用內存較大的對象不要隨便使用autorelease
- 佔用內存較小的對象使用autorelease,沒有太大影響
- 錯誤寫法:
- alloc以後調用了autorelease,又調用release
@autoreleasepool {
//1
Person *p = [[[Person alloc]init]autorelease];
//0,野指針錯誤
//[p release];
}
@autorelease
{
Person *p = [[[[Person alloc]init]autorelease]autorelease];
}
- 自動釋放池
- 在ios程序運行過程當中,會建立無數個池子,這些池子都是以棧結構存在(先進後出)
- 當一個對象調用autorelease方法時,會將這個對象方到棧頂得釋放池
- 自動釋放池的建立方式
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Person *pp = [[[Person alloc]init]autorelease];
[pool release];
@autorelease
{
}
- autorelease的使用場合
- 系統自帶的方法裏面沒有包含alloc、new、copy,說明返回的對象都時autorelease的
- 開發中常常會提供一些類方法,快速建立一個autorelease過的對象
- 建立對象時,不要直接用類名,通常用self
+ (id)person
{
return [[[self alloc] init]autorelease];
}