我现在正从ARC切换到MRC,因为我选择了一个旧项目。但是我不熟悉MRC,现在当我分析我的代码时,对象属性可能会泄漏。
这是代码
@property (nonatomic, retain) NSString *string;
@property (nonatomic, retain) AnotherObject *anotherObject;
- (id)init{
...
_string = [[NSSting alloc] init];
...
}
- (void)doThings{
self.anotherObject.text = self.string; // text is also a retain property of anotherObject,and anotherObject is also a property
}
- (void)dealloc{
[_string release];
[_anotherObject release];
...
}
我尝试修复它,因此我将_string
设为自动释放对象
- (id)init{
...
_string = [[[NSSting alloc] init]autorelease];
...
}
并且仍然在_string
方法中发布dealloc
,它可以工作,当我再次分析我的代码时,潜在的泄漏消失了。
但我无法弄明白为什么,有人可以帮我解释一下吗?非常感谢你。
答案 0 :(得分:0)
正确的模式是您最初尝试过的模式。在init
中分配您的ivar而不进行自动释放,例如:
_string = [[NSString alloc] init];
并在dealloc
中发布,如:
[_string release];
如果使用属性的setter,则需要使用autorelease,因为属性(使用retain
声明)将保留您为其指定的对象。因此,如果您使用self.string = ...
分配字符串属性,那么它应该如下所示:
self.string = [[[NSString alloc] init] autorelease];
在你的问题中,你说静态分析仪发现错误。如果您查看Xcode中问题选项卡中的静态分析器消息,您实际上可以扩展分析问题,Xcode将显示分析器查看潜在泄漏的代码路径。这可以真正帮助追踪这些问题。
答案 1 :(得分:0)
在初始化方法中,您正在分配字符串。所以这意味着你的变量是对象的所有者。但是,当它的工作完成后,它仍然保留着这个目标。因此,在这种情况下,您将收到潜在的泄漏警告。
但是在你自动释放之后,所以它在工作完成时释放了对象。所以你的潜在泄漏已经消失了。
Autorelease只是从对象中删除一个保留计数,它不像c中那样立即“释放”内存。当自动释放池结束时,所有自动释放的对象计数为0将释放其内存。