使用“保留”对象泄漏

时间:2011-02-23 23:19:10

标签: iphone cocoa-touch ios retaincount

我有一个使用retain属性定义的属性,我正在合成:

@property (nonatomic, retain) UISwitch *mySwitch;

在我的loadView中我正在这样做:

self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];

最后在我的dealloc里面,我正在这样做:

self.mySwitch = nil;

我是否因为使用了一个alloc而泄漏了这个对象(mySwitch)?我应该在分配帧时自动发布吗?

请建议。

4 个答案:

答案 0 :(得分:4)

该行:

self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];

实际上调用会保留两次 - 一次针对alloc,再次分配给self.mySwitch(这是您指定的属性retain分配给它的值。)我被告知最好的解决方法是在线路上添加autorelease的呼叫,使其成为:

self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];

答案 1 :(得分:2)

是的,你在泄漏。您正在使用+alloc/-initWithFrame:创建拥有的对象,然后将该拥有的对象分配给标记为retain的属性。这将创建对该对象的第二个拥有引用。此时,您泄漏原始拥有的引用,这会导致对象本身泄漏。

这里的正确行为是在将对象分配给属性之前调用-autorelease

self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];

在切线说明中,不建议您访问-dealloc内的属性。通常给出的两个原因是1)这将广播KVO通知,你不想在-dealloc内,2)如果有人覆盖了setter(在这个类或子类中)它可能不会表现正常。推荐的方法是简单地释放底层的ivar,所以你会看到类似下面的内容:

[mySwitch release];

在其他地方分配nil非常安全(并推荐)。

答案 2 :(得分:1)

作为autorelease的替代方案,如果您需要更严格的内存管理,这应该适合您:

UISwitch *myswitch_tmp= [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
self.mySwitch = myswitch_tmp;
[myswitch_tmp release];

以及之后,例如在dealloc

[mySwitch release];

答案 3 :(得分:-4)

是。你正在泄漏物体。请记住一条简单的规则:

如果您使用+alloc,则始终必须有相应的-release