使用手動引用計數時的記憶體管理規則

這些規則僅適用於你使用手動引用計數的情況!

  1. 你擁有自己建立的任何物件

    通過呼叫名稱以 allocnewcopymutableCopy 開頭的方法。例如:

    NSObject *object1 = [[NSObject alloc] init];
    NSObject *object2 = [NSObject new];
    NSObject *object3 = [object2 copy];
    

    這意味著當你完成這些物件時,你有責任釋放這些物件。

  2. 你可以使用 retain 獲取物件的所有權

    要獲取物件的所有權,請呼叫 retain 方法。

    例如:

    NSObject *object = [NSObject new]; // object already has a retain count of 1
    [object retain]; // retain count is now 2
    

    這在某些罕見情況下才有意義。

    例如,當你實現訪問者或 init 方法來獲取所有權時:

    - (void)setStringValue:(NSString *)stringValue {
        [_privateStringValue release]; // Release the old value, you no longer need it
        [stringValue retain]; // You make sure that this object does not get deallocated outside of your scope.
        _privateStringValue = stringValue;
    }
    
  3. 當你不再需要它時,你必須放棄你擁有的物件的所有權

    NSObject* object = [NSObject new]; // The retain count is now 1
    [object performAction1]; // Now we are done with the object
    [object release]; // Release the object
    
  4. 你不得放棄你不擁有的物件的所有權

    這意味著當你沒有取得物件的所有權時,你不會釋放它。

  5. Autoreleasepool

    autoreleasepool 是一個程式碼塊,用於釋放接收自動釋放訊息的塊中的每個物件。

    例:

    @autoreleasepool {
        NSString* string = [NSString stringWithString:@"We don't own this object"];
    }
    

    我們建立了一個不佔用所有權的字串。NSString 方法 stringWithString:必須確保在不再需要字串後正確解除分配。在方法返回之前,新建立的字串呼叫 autorelease 方法,因此它不必取得字串的所有權。

    這就是 stringWithString:的實現方式:

    + (NSString *)stringWithString:(NSString *)string {
        NSString *createdString = [[NSString alloc] initWithString:string];
        [createdString autorelease];
        return createdString;
    }
    

    有必要使用 autoreleasepool 塊,因為你有時擁有自己不擁有的物件(第四條規則並不總是適用)。

    自動引用計數會自動處理規則,因此你不必這樣做。