我知道,在Objective-C中,有一种非常简单的方式来声明这样的变量:

NSArray* myArray;

@property(retain) NSArray* myArray;

@synthesize myArray;

这样,您可以在保留变量的同时使用self.myarray作为设定器和Getter。但是,这也可以让您做更多的事情,即避免使用DealLoc。据我了解,这两行是相同的:

self.myArray = nil;
[myArray release];

我的问题是,哪种是首选的方法?是否有任何情况下,其中一个会起作用,而另一个则不会?

编辑:对不起,我的意思是发布,而不是DealLoc ...

有帮助吗?

解决方案

底部更新。

在使用(保留)合成属性时,完成DealLoc职责的最佳方法是将属性设置为零。我说这是“最好的”方法的原因是,它可以确保符合财产声明所隐含的所有合同。例如,如果您的财产被声明为原子(除非您特别声明非原子)确保在DealLoc上进行此属性的不设置的唯一方法是使用相同的原子保证完成的,就是将其设置为nil Dealloc的财产。这也意味着它将对您对象的任何键值观测值正确行为 - 这可能很重要,尤其是如果您使用可可绑定。

当自己为没有相应属性的(也许是私有)实例变量进行自己的内存管理时,有几个习语。最简单但最危险的是简单地释放ivar,就像这样:

- (void)dealloc
{
    [myArray release];

    [super dealloc];
}

这将导致伊瓦尔(Ivar)上的保留释放,但正如其他人提到的那样,将使现在的电位指针留下可能存在的,如果错误地,可以通过陈旧或非滞留指针访问,可能存在的指向对象是对象的交易。接下来是另一个答案提出的习语:

- (void)dealloc
{
    [myArray release], myArray = nil;

    [super dealloc];
}

一个更安全的,即使更加学先的话,这个习语是:

- (void)dealloc
{
    id temp = myArray;
    myArray = nil;
    [temp release];

    [super dealloc];
}

这进一步限制了在释放指向对象之前清除ivar的陈旧读取指针的机会。但是,由于有可能重新排序的说明,即使这也不能100%保证所有架构上的陈旧阅读。

尽管关于并发和内存管理的主题还有很多要说的话,但通常,如果您有@synthised属性设置器,则应在DealLoc中使用它。这样做意味着,如果您更改@property的行为,那么DealLoc行为将自动相对于@property声明是正确的。

重要说明:使用原子属性!=线程安全。 (实际上,如果您问我原子特性是浪费,但是...)请参阅 这里 更多细节。

更新

最近,这再次受到了投票,尽管我在这里说明了与合成的保留属性有关的原子保证,而原始答案中的其他一些内容本身是有价值的,但我觉得有必要告诉另一面故事。戴夫·德隆(Dave DeLong)在评论中暗示了其中的一些,但我认为值得将细节添加到主要答案中。

我坚持认为,维持原子能保证的唯一方法是将财产设置为 nil 通过设置器。 您不应该关心,这就是为什么:如果一个物体正在 dealloced,这意味着(如果您的对象图是正确的,则不应对该对象有生命参考。如果没有对物体的生命参考,那么任何人都不可能关心清除该财产的操作的原子能保证。

我还提到了原始答案中的kvo作为使用二阶的原因 dealloc, ,但戴夫·德隆(Dave DeLong)在评论中提到了KVO作为对立面。他是对的,这就是为什么:同样,如果一个物体正在 dealloc埃德(Ed),所有的KVO观察者都应该已经从中删除了(同样,应该没有生命参考,KVO是否应该)。确实,如果不是这种情况,直到您看到主机消息告诉您您的对象仍然存在观察值之前,不会很长时间。

简而言之,虽然您无法使原子性保证与合成二传剂的原子保证 dealloc, ,它绝不重要(如果有的话,其他东西都被打破了。)

其他提示

您绝不应该自己打电话给DealLoc(在非常非正统的情况下除外)。

您应该致电,而不是DealLoc [myArray release] 并让发布的过程为您服务。

看一看 这里 对于您在DealLoc方法上的信息比您想要的更多信息。

每当您具有任何是对象的实例变量时,就必须在dealLoc方法中发布它。因此,就您而言,您必须使用

- (void)dealloc
{
    [myArray release], myArray = nil;

    [super dealloc];
}

理论上的设置与释放ivar相同。但是,您绝对不要直接调用DealLoc方法。在DealLoc方法中,您有时会看到David提到的成语,特别是:

[myArray release], myArray = nil;

这样做的原因是要避免不太可能的种族条件,在DealLoc完成之前,有人可能会尝试访问已发布的对象。通过将属性分配给零,这允许尝试访问的访问权限。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top