2

当一个 NSString 对象作为参数传入时,我应该总是这样做retainrelease

-forExample:(NSString*)str{
    [str retain];

    //do something

    [str release];
}

或不?我应该在何时何地使用它?

4

2 回答 2

4

该对象的引用计数不会在此方法的过程中发生变化,因此没有理由发送它retain。来自 Apple 的内存管理文章(你绝对应该看一下):

如果您从程序的其他地方收到一个对象,通常保证它在接收它的方法或函数中保持有效。如果您希望它在该范围之外保持有效,您应该保留或复制它。如果你试图释放一个已经被释放的对象,你的程序就会崩溃。

只有当您需要一个对象停留在当前范围之外时,您才需要保留它。

- (void) forExample: (NSString *)theString {
    // Will need this object later. Stuff it into an ivar and retain it.
    // myString = [theString retain];    
    // For NSString, it's actually better to copy, because this
    // could be a _mutable_ string, and it would in fact be best to use
    // the setter for the ivar, which should deal with the memory management:
    [self setMyString:theString];

    // Do things...

    // Don't release.
}

如果您保留了一个对象,那么您需要在release不再需要它时发送它。

- (void) otherExample {
    [myString doYourStringThing];
    // If you don't need the string past this point (which would be slightly
    // unusual -- it leaves an ivar unset) release it and set it to nil.
    // [myString release]; myString = nil;
    // Again, it would be best to use the setter:
    [self setMyString:nil];
}

// Generally you keep ivars around until the instance is deallocated,
// and release them in dealloc
- (void) dealloc {
    [myString release];
    [super dealloc];
}
于 2011-10-26T02:08:20.743 回答
0

你也不应该这样做,因为就像一个优秀的开发人员一样,你正在跟上 Objective-C 的最新趋势并使用自动引用计数。自动引用计数消除了手动调用保留/释放的需要,并带有 LLVM 3.0 和 Xcode 4.2。

如果出于某种原因,您想像这里一样使用手动内存管理,在大多数情况下,您不应该手动调用retain和。release通常,可以使用您的判断而不单独保留每个论点。

这可能是一个好主意的唯一情况是,如果您的方法在某些时候调用回调或可能会在您使用它之前释放参数的东西。例如,如果您的函数接受一个块并在其执行期间调用该块,则可能会出现这种情况。如果该块释放作为参数传递的对象,然后在调用该块后使用该对象,则该参数本质上是一个悬空指针。

这种情况的例子

- (void)myFunction:(NSString *)foo block:(void (^)())callback {
    [foo retain];
    callback();
    // .. do some stuff
    [foo release];
}

- (void)myCallingFunction {
    NSString * myVariable = [[NSString alloc] initWithString:@"Test"];
    [self myFunction:myVariable block:^ {
        [myVariable release];
    }];
}

如您所见,代码[myVariable release]将在// .. do some stuff注释之前到达。

于 2011-10-26T02:31:23.060 回答