为什么myInstance = nil而不是self.myInstance = nil?

时间:2011-02-04 06:27:36

标签: ios memory-management

为什么我会使用(在我的dealloc方法中)?

  1. [myInstance release]代替[self.myInstance release]
  2. myInstance = nil代替self.myInstance = nil
  3. 虽然我们使用self.myInstance = [[[AClass alloc] init] autorelease]代替myInstance = [[[AClass alloc] init] autorelease]

    这些做法来自我在网上看到的众多例子。

6 个答案:

答案 0 :(得分:1)

调用self.myInstance =使用自动生成的setter方法。调用[self.myInstance release];调用释放getter方法返回的对象。这一切都取决于您的属性设置方式(保留,分配?)。您的问题没有一定的正确或错误答案,因为这完全取决于相关财产。我建议你阅读Objective C properties以更好地了解这类事情。

并且,除非myInstance被声明为assign,否则你不想打电话给self.myInstance = [[AClass alloc] init]你可以用self.myInstance = [[[AClass alloc] init] autorelease]

来改善

答案 1 :(得分:1)

这取决于您在界面中定义的属性。例如,如果您定义retain属性:

@property (nonatomic, retain) NSObject *property;

然后你可以在dealloc方法中使用self.property = nil;,因为它等于:

[property release]; // releases previous property
property = [nil retain]; // [nil retain] returns just nil

self.property = [[A alloc] init];完全相同。这等于

[property release]; // releases previous property
property = [[[A alloc] init] retain];

如果property = [[A alloc] init];属性不会被保留。

Here's Apple的完整资产指南。

答案 2 :(得分:1)

  

1)[myInstance release]而不是[self.myInstance release]

更喜欢前者。

当子类重写方法self.myInstance时,myInstance的返回值由实现定义。你对dealloc期间构造对象的接口行为不感兴趣(因为子类可能会覆盖并返回除了你的ivar之外的东西)。

你对dealloc感兴趣的是在你的对象被销毁之前释放你拥有的引用。如果子类已覆盖myInstance,则它可以:

a)返回一个已经被释放的ivar(在子类中声明)

b)覆盖的实现可能会返回一个新创建的自动释放对象

a或b可能导致过度释放和崩溃(假设其他所有内容都被正确保留/释放)。这也表明为什么你应该在释放之后给它分配nil。

这也是如何触发对象复活的典型例子。当您调用的getter / setter的实现在已经解除分配后重新创建其状态时,就会发生对象复活。最不具攻击性的副作用会导致无害的泄漏。

  

2)myInstance = nil而不是self.myInstance = nil

再次,更喜欢前者。

正式回复看起来很像对#1的回应 - 理由,副作用和危险也适用于此。

最安全的方法是直接访问ivar:

[myInstance release], myInstance = nil;

因为可能存在非常难以复制的令人讨厌的副作用(崩溃,泄漏,复活)。

可以轻松避免这些危险,并且您的代码将更容易维护。另一方面,如果人们在使用你的程序时遇到副作用,他们可能会避免(重新)在任何地方使用它。

祝你好运

答案 3 :(得分:1)

请注意使用

myInstance = nil

而不是

self.myInstance = nil

如果myInstance是一个retain属性,那么(在UIViewController子类中的一个viewDidUnload方法的上下文中)是不正确的,因为如果myInstance指向一个对象,它将被泄露!

答案 4 :(得分:0)

实际上使用

self.myInstance = [[AClass alloc] init];

会导致内存泄漏,导致self.myInstance正在使用setter方法,这会导致retain +1以及alloc / init retain +1。所以你得到一个保留计数+2;

答案 5 :(得分:0)

... = self.myInstance

self.myInstance = ...

实际上是对getter和setter的子例程或方法调用,这取决于您如何定义这些子例程,或者让Objective C Properties创建它们,几乎可以做任何事情。

如果保留属性的情况,子例程可能会使用保留计数。如果您使用自己的吸气剂和定位器,您可以让它们控制您家中的灯光,将它们打开为零,并在设置为零或零时将灯关闭。甚至不需要是名为“instance”的支持变量,可以通过以下方式设置:

instance = ...