使用手动引用计数时的内存管理规则

这些规则仅适用于你使用手动引用计数的情况!

  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 块,因为你有时拥有自己不拥有的对象(第四条规则并不总是适用)。

    自动引用计数会自动处理规则,因此你不必这样做。