Cocoa 程式設計/記憶體管理
有人,請修復此頁面
在 Objective-C(與 C++ 不同)中,所有物件都是動態建立的。這意味著它們將一直存在,直到它們被明確銷燬。
要建立一個物件,請向其類傳送一個分配訊息[aClass alloc];。請注意,這將返回一個新類的例項,但不會初始化其資料。通常您希望立即向新物件傳送一個初始化訊息來彌補這一點。分配和初始化通常在一行程式碼中結合在一起
aClass *newobj = [[aClass alloc] init];
有一個名為新的類方法,它分配並提供物件的基本初始化,但已棄用,取而代之的是分配和初始化.
在 C++ 中,每個動態建立的物件都需要顯式刪除(使用刪除運算子)。在 Java 中,每個動態建立的物件(即每個物件)都會在垃圾收集器檢測到物件不再被引用時自動刪除。在 Objective-C 中,沒有使用這兩種方法。
Objective-C 物件維護一個引用計數。當建立物件時,其引用計數初始化為 1。當引用計數達到零時,物件將自行銷燬。
要告訴物件您不再使用它,請向它傳送一個釋放訊息:"[anObject release];". 這會將物件的引用計數減 1。如果您是物件的最後一個使用者,該物件將自行銷燬。
在傳送釋放到物件之後,不安全再使用該物件,因為該物件可能已自行銷燬。
當您要保留一個物件,即阻止它消失時,請向它傳送一個保留訊息:"[anObject retain];". 請注意,您不應向使用分配訊息建立的物件傳送保留訊息,因為分配始終意味著保留。因此,保留僅在您需要使用在其他地方建立的物件(並且將在該部分程式不再需要它時從那裡傳送釋放訊息)時才需要。
每個保留都需要與一個且僅一個釋放匹配。請注意,新, 分配, 複製和可變複製方法也隱式地保留返回的物件,因此這些方法也需要與釋放.
有時無法立即釋放物件:例如,函式建立了一個物件並希望將其返回給呼叫者。現在,被呼叫者應釋放它建立的不再使用的物件。但是,呼叫者需要訪問返回的物件。如果被呼叫者釋放建立的物件,呼叫者將永遠看不到返回值。一個解決方案是在被呼叫者中跳過釋放物件,並要求呼叫者釋放它。這很容易出錯,並且違反了“每個保留與一個釋放匹配”的原則。
在 Objective-C/OpenStep 執行時,可以向物件傳送自動釋放訊息。這將導致物件被新增到當前的自動釋放池中。自動釋放池中的物件將在將來的某個時間點(當前自動釋放池被銷燬時)被釋放。在之前,它們是安全的。
如果呼叫者想保留返回的物件,它必須保留它。否則,該物件將被自動釋放。示例
/* In class Environment, responsible of telling details of current environment: */
- (id) nameOfLang /* the callee */
{
id name = [[NSString alloc] initWithCString: "Objective-C"];
[name autorelease];
return name;
}
/* In another class where environment info is needed */
- (void) getName /* the caller */
{
myLangName = [environment nameOfLang]; /* myLangName is an instance variable */
[myLangName retain]; /* Will be released when this object no longer needs it */
}