首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用"retain“的对象泄漏

使用"retain“的对象泄漏
EN

Stack Overflow用户
提问于 2011-02-24 07:19:10
回答 4查看 199关注 0票数 1

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

代码语言:javascript
复制
@property (nonatomic, retain) UISwitch *mySwitch;

在我的loadView中,我这样做:

代码语言:javascript
复制
self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];

最后,在我的dealloc中,我要这样做:

代码语言:javascript
复制
self.mySwitch = nil;

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

请提个建议。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-24 07:21:54

这行代码:

代码语言:javascript
复制
self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];

实际上调用了retain两次-一次是为alloc,另一次是在赋值给self.mySwitch (这是您已经指定的属性,应该为它分配任何值)。我被告知的最好的解决办法是在线路上添加一个对autorelease的调用,使其如下:

代码语言:javascript
复制
self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];
票数 4
EN

Stack Overflow用户

发布于 2011-02-24 07:21:57

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

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

代码语言:javascript
复制
self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];

顺便说一句,我们不建议您访问-dealloc内部的属性。通常给出的两个原因是: 1)这将广播KVO通知,这在-dealloc中是不需要的;2)如果任何人覆盖了设置器(在这个类或子类中),它可能不会正常运行。推荐的方法是简单地释放底层的ivar,这样您就会看到类似以下的内容:

代码语言:javascript
复制
[mySwitch release];

将nil赋值给该属性在任何其他地方都是完全安全的(也是推荐的)。

票数 2
EN

Stack Overflow用户

发布于 2011-02-24 08:00:35

作为自动释放的替代方案,如果你需要更严格的内存管理,这对你来说应该是可行的:

代码语言:javascript
复制
UISwitch *myswitch_tmp= [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
self.mySwitch = myswitch_tmp;
[myswitch_tmp release];

稍后,例如,在取消分配时

代码语言:javascript
复制
[mySwitch release];
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5098549

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档