誰創建,誰release
➢ 如果你通過alloc、new或[mutable]copy來創建一個對象,那麼你必須調用release或autorelease
➢ 換句話說,不是你創建的,就不用你去[auto]release誰retain,誰release
➢ 只要你調用了retain,無論這個對象是如何生成的,你都要調用release總結
➢ 有始有終,有加就有減
➢ 曾經讓對象的計數器+1,就必須在最後讓對象計數器-1
set方法的內存管理
如果你有個OC對象類型的成員變量,就必須管理這個成員變量的內存。比如有個Book *_book
1. set方法的實現
- (void)setBook:(Book *)book{
if (book != _book) {
[_book release];
_book = [book retain];
}
}
- dealloc方法的實現
- (void)dealloc {
[_book release];
[super dealloc];
}
- (void)dealloc {
@property參數
控制set方法的內存管理
➢ retain : release舊值,retain新值(用於OC對象)
➢ assign : 直接賦值,不做任何內存管理(默認,用於非OC對象類型)
➢ copy : release舊值,copy新值(一般用於NSString *)控制需不需生成set方法
➢ readwrite :同時生成set方法和get方法(默認)
➢ readonly :只會生成get方法多線程管理
➢ atomic :性能低(默認)
➢ nonatomic :性能高控制set方法和get方法的名稱
➢ setter : 設置set方法的名稱,一定有個冒號:
➢ getter : 設置get方法的名稱
循環引用
- @class
➢ 使用場景
對於循環依賴關係來說,比方A類引用B類,同時B類也引用A類
這種代碼編譯會報錯。當使用@class在兩個類相互聲明,就不會出現編譯報錯
➢ 用法概括
使用 @class 類名; 就可以引用一個類,說明一下它是一個類
➢ 和#import的區別
#import方式會包含被引用類的所有信息,包括被引用類的變量和方法;@class方式只是告訴編譯器在A.h文件中 B *b 只是類的聲明,具體這個類裏有什麼信息,這裏不需要知道,等實現文件中真正要用到時,纔會真正去查看B類中信息
如果有上百個頭文件都#import了同一個文件,或者這些文件依次被#improt,那麼一旦最開始的頭文件稍有改動,後面引用到這個文件的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方式就不會出現這種問題了
在.m實現文件中,如果需要引用到被引用類的實體變量或者方法時,還需要使用#import方式引入被引用類
循環retain
➢ 比如A對象retain了B對象,B對象retain了A對象
➢ 這樣會導致A對象和B對象永遠無法釋放解決方案
➢ 當兩端互相引用時,應該一端用retain、一端用assign
autorelease
autorelease
➢ 給某個對象發送一條autorelease消息時,就會將這個對象加到一個自動釋放池中
➢ 當自動釋放池銷燬時,會給池子裏面的所有對象發送一條release消息
➢ 調用autorelease方法時並不會改變對象的計數器,並且會返回對象本身
➢ autorelease實際上只是把對release的調用延遲了,對於每一次autorelease,系統只是把該對象放入了當前的autorelease pool中,當該pool被釋放時,該pool中的所有對象會被調用Release自動釋放池的創建
➢ ios 5.0後
@autoreleasepool
{
// ….
}
➢ ios 5.0前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// …..
[pool release]; // 或[pool drain];
➢ 在程序運行過程中,可以創建多個自動釋放池,它們是以棧的形式存在內存中
➢ OC對象只需要發送一條autorelease消息,就會把這個對象添加到最近的自動釋放池中(棧頂的釋放池)應用實例
➢ 跟release的對比
以前:
Book *book = [[Book alloc] init];
[book release];
現在:
Book *book = [[[Book alloc] init] autorelease];
// 不要再調用[book release];
➢ 一般可以爲類添加一個快速創建對象的類方法
+ (id)book {
return [[[Book alloc] init] autorelease];
}
外界調用[Book book]時,根本不用考慮在什麼時候釋放返回的Book對象
- 規律
➢ 一般來說,除了alloc、new或copy之外的方法創建的對象都被聲明瞭autorelease
➢ 比如下面的對象都已經是autorelease的,不需要再release
NSNumber *n = [NSNumber numberWithInt:100];
NSString *s = [NSString stringWithFormat:@"jack"];
NSString *s2 = @"rose";