我有一个使用retain属性定义的属性,我正在合成:
@property (nonatomic, retain) UISwitch *mySwitch;
在我的loadView中我正在这样做:
self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
最后在我的dealloc里面,我正在这样做:
self.mySwitch = nil;
我是否因为使用了一个alloc而泄漏了这个对象(mySwitch)?我应该在分配帧时自动发布吗?
请建议。
答案 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
。