在我的setter中,我有一个我要复制的传入字符串,以避免在修改原始文件时出现任何问题。
- (void)setName:(NSString *)newName{
if(name != newName) {
[name release];
name = [newName copy];
}
}
我的问题是:因为我正在复制我应该在哪里发布它,还是我只是自动释放?即。
- (void)setName:(NSString *)newName{
if(name != newName) {
[name release];
name = [[newName copy] autorelease];
}
}
加里
答案 0 :(得分:6)
执行copy
时,将保留该对象。 这就是你想要的。如果你自动发布它,它最终会被解除分配。所以你的第一个例子是正确的。第二个会崩溃你的应用程序。
如果您担心在取消分配对象时会发生什么,请记住您应release
dealloc
方法中的任何引用。
答案 1 :(得分:4)
在我的setter中,我有一个我要复制的传入字符串,以避免在修改原始文件时出现任何问题。
- (void)setName:(NSString *)newName{ if(name != newName) { [name release]; name = [newName copy]; } }
我的问题是:因为我正在复制我应该在哪里发布它,还是我只是自动释放?即。
- (void)setName:(NSString *)newName{ if(name != newName) { [name release]; name = [[newName copy] autorelease]; } }
正如我在your other question上所说,autorelease
转换为“稍后发送给自己release
”。这意味着它算作一个版本。
所以,你的第二个例子释放旧值name
(好),然后复制新的(好),然后将新的一行放到行中(坏),然后放这个现在注定的对象进入了实例变量(非常糟糕)。
第一个示例是正确的,因为在将对象放入实例变量后仍然保留对象。
正如我在你的另一个问题上所说,我认为你应该检讨the memory-management rules。
答案 2 :(得分:1)
您的第一个样本是正确的:
- (void)setName:(NSString *)newName{
if(name != newName) {
[name release];
name = [newName copy];
}
}
但是您怀疑,copy
必须与release
平衡。假设name
具有通常的语义(即,您希望它保持不变,直到包含类的实例被释放),平衡release
应该在dealloc
中(假设您不是使用垃圾收集):
- (void)dealloc {
[name release];
//release other instance variables of type id
[super dealloc];
}
如果您仍然感到困惑,请重读内存Management Programming Guide for Cocoa。
答案 3 :(得分:1)
你的第一个例子是正确的。 Peter Hosey也是如此 - 您应该更好地熟悉内存管理规则。
如果它有帮助,我的首选方法看起来更清洁:
- (void)setName:(NSString *)name
{
name = [name copy];
[_name release];
_name = name;
}