以下声明中是否存在保留/释放问题;
xyzProp = [NSMutableString stringWithString:@"Report error"];
我收到一个错误,我认为是上述声明
xyzProp是一个属性,我在dealloc中使用它。
答案 0 :(得分:2)
您不应该释放此对象,因为您没有分配它。
“stringWithString”方法将返回一个自动释放的对象,因此您应该让它自动释放,或保留它然后释放它。
作为一般规则,您应该只发布使用以下内容创建的对象:
任何其他方法都将返回一个自动释放的对象。
修改强>
xyzProp只是一个成员变量,而不是属性。如果将属性声明为(保留),则生成的setter方法将为您保留任何新值。如果直接设置成员变量,则还应保留未分配的任何内容。
答案 1 :(得分:1)
stringWithString
返回一个自动释放的字符串。
尽管xyzProp是一个属性,但是您的代码直接分配引用而不通过xyzProp的setter,这不会增加该字符串的retainCount。这意味着将来某个时候会释放这个字符串,这可能会在调用对象的dealloc之前发生。
将字符串声明为保留属性。
@property (nonatomic, retain) NSMutableString *xyzProp;
并在设置时使用setter。
self.xyzProp = [NSMutableString stringWithString:@"Report error"];
苹果生成的setter看起来有点像这样,
- (void)setXyzProp:(NSMutableString *)aString {
if (aString == xyzProp) {
return;
}
NSMutableString *oldValue = xyzProp;
xyzProp = [aString retain];
[oldValue release];
}
调用self.xyzProp = ...
与调用[self setXyzProp:...]
相同,确保调用setter,然后在传入的字符串上调用retain。
<强>更新强>
设置字符串时,您几乎总是希望copy
而不是retain
,尤其是在这种情况下,因为传递了NSMutableString
。原因是字符串值可能会从对象外部更改,而对象不知道哪个可能导致意外行为。
答案 2 :(得分:0)
xypProp
本身不属性 - 它必须是支持属性的实例变量。在那种情况下,是的,这是一个错误。你将一些你不拥有的东西分配给一个实例变量,所以它可能会从你身下消失 - 释放它肯定是错的,因为问题在于你首先不拥有它。要使用属性设置器(这是正确的),它必须是self.xyzProp = [NSMutableString stringWithString:@"Report error"];
。
答案 3 :(得分:0)
stringWithString:
正在返回一个自动释放的对象,因为你只是在这里使用赋值(而不是属性),那么当你尝试在dealloc
方法中释放它时,你会收到一个错误(因为你从未在这门课程中保留过它。)
如果你的xyzProp确实是一个属性,并且在声明中有retain属性,那么你可以使用属性setter方法,如下所示:
self.xyzProp = [NSMutableString stringWithString:@"Report error"];
这可能是你打算做的。如果你仍然感到困惑,我建议你参考Apple的属性编程指南。