当NSString对象作为参数传入时,我应该始终retain
和release
:
-forExample:(NSString*)str{
[str retain];
//do something
[str release];
}
是不是?我应该在何时何地使用它?
答案 0 :(得分:4)
该方法的引用计数在此方法的过程中不会改变,因此没有理由发送它retain
。来自Apple的Memory Management essay(你一定要查看):
如果从程序中的其他位置收到对象,通常会保证在收到的方法或函数中保持有效。如果您希望它在该范围之外保持有效,则应保留或复制它。如果您尝试释放已经解除分配的对象,则程序崩溃。
您只需要在需要时保留一个对象,以便超越当前范围。
- (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];
}
答案 1 :(得分:0)
你永远不应该这样做,因为,像一个优秀的开发人员一样,你正在跟上Objective-C的最新趋势并使用Automatic Reference Counting。自动引用计数消除了手动调用保留/释放的需要,并附带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
评论之前到达。