【问题标题】:What's the best way to release objective-c properties?释放objective-c属性的最佳方式是什么?
【发布时间】:2011-01-29 12:39:13
【问题描述】:

我是内存管理的新手,并且正在阅读有关如何最好地释放属性的不同内容。

如果我有:
在 .h 中:

@property(retain) NSString *myStr;

在.m中:

@synthesize myStr = _iVarStr;

如果我的 dealloc 有:

[_iVarStr release];  

self.myStr = nil;   

还是别的什么?

谢谢!

【问题讨论】:

  • 在相关说明中,尽可能尝试使用“非原子”属性。根据 Apple 的说法,它可以显着提高性能(如果您进入多线程编程,则需要承担一些风险)。
  • 我会推荐阅读这个帖子:stackoverflow.com/questions/1458178/…
  • 答案是否可能取决于 setter 和 getter 的实现/合成方式?
  • 是的 - 好消息。为简洁起见,省略了非原子。
  • 谢谢 - 读得很好。

标签: iphone objective-c xcode memory-management properties


【解决方案1】:

self.myStr = nil[myStr release] 最终都会做同样的事情。

调用[myStr release] 很明显,只需释放它即可。

同时,myStr 的 setter 方法大致如下所示:

- (void)setMyStr:(NSString *)newMyStr
{
    [newMyStr retain];
    [myStr release];
    myStr = newMyStr;
}

所以当我们执行self.myStr = nil 时,我们首先会保留一个 nil 对象,它什么都不做。然后我们释放旧变量,这就是我们想要的。最后,我们将指针设置为 nil。

有什么区别?后者将指针设置为 nil。这更好,因为如果我们(不小心)向释放的对象发送消息,如果指针不为零(EXC_BAD_ACCESS),我们就会崩溃。现在老实说,既然你在 -dealloc 中,对象无论如何都会被销毁,所以你使用什么并不重要。

【讨论】:

  • 这回答了我关于合成 setter 和 getter 的原始问题。不过,我很清楚,对于自定义设置器或不同的属性属性,答案可能会有所不同。 Remover 的回复也很有帮助 - stackoverflow.com/questions/1458178/… 感谢回复!
【解决方案2】:

当一个属性设置为保留时

self.ivar = nil;

将正确管理内存分配。对于其他属性类型,请查看official documentation 页面。它还有一堆示例代码,因此您可以了解所有选项的“幕后”发生了什么。

【讨论】:

  • 是的。 Saurabh 的答案中列出的代码非常接近合成的转换器。
【解决方案3】:

你的 dealloc 应该是这样的:

- (void)dealloc {
  [_iVarStr release];
  [super dealloc];
}

虽然将属性设置为 nil 是可能的,但我担心可能不会意识到对象当前正在被释放的更改触发的意外副作用或 KVO 操作。

【讨论】:

  • 请解释为什么这是自找麻烦。
  • 说明为什么应该在dealloc 中使用属性设置器的示例:stackoverflow.com/questions/192721#192852
  • 永远不要说永远。有时,在 dealloc 中设置属性是有意义的(尤其是当 setter 具有一些重要的副作用时,例如设置观察者)。
  • 是的,请解释更多。关于内存管理,如果您在发布后评估 _iVarStr != nil,它会返回 false。 self.myStr = nil 并非如此。
  • 如果你的 setter 有很多副作用,你不应该一开始就使用属性。 setter 的任何副作用都只能是坏的,毕竟您将“新值”设置为 nil 并即将释放整个对象。真正的麻烦在于,setter 更改可能会向某些观察者发出 KVC 通知,然后这些观察者会尝试对大部分或部分释放的对象进行操作。如果您设置了通知,那么您需要在 dealloc 中明确将自己移除为观察者,而不是依赖副作用为您执行此操作。
【解决方案4】:

我建议你在dealloc方法中使用self.ivar=nil(我之前写的代码ivar=nil是错误的)方式。因为,如果 ivar 的属性从保留更改为分配(或从分配更改为保留),您不必更改代码。

【讨论】:

  • 如果您的 ivars 是 assign,那么您必须格外小心,不要从您下方释放您的对象。
  • 这对我来说没有意义,因为仅将内部 ivar 设置为 nil 并不会释放它 - 这对于分配属性有意义但不保留。
  • 对不起,我弄错了。确切的方法是self.ivar=nil。只有ivar=nil 不好。
猜你喜欢
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 2011-12-11
  • 2010-11-30
  • 1970-01-01
相关资源
最近更新 更多