【问题标题】:Why myInstance = nil instead of self.myInstance = nil?为什么 myInstance = nil 而不是 self.myInstance = nil?
【发布时间】:2011-02-04 06:27:35
【问题描述】:

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

  1. [myInstance release] 而不是 [self.myInstance release]
  2. myInstance = nil 而不是 self.myInstance = nil

虽然我们使用self.myInstance = [[[AClass alloc] init] autorelease] 而不是myInstance = [[[AClass alloc] init] autorelease]

这些做法来自我在网上看到的大量示例。

【问题讨论】:

  • 请搜索网站。这个问题之前已经出现过很多次了。

标签: ios memory-management


【解决方案1】:

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

更喜欢前者。

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

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

a) 返回一个已经发布的 ivar(在子类中声明)

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

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

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

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

再次,更喜欢前者。

正式的回应看起来很像对#1的回应——基本原理、副作用和危险也适用于此。

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

[myInstance release], myInstance = nil;

因为可能存在难以重现的非常糟糕的副作用(崩溃、泄漏、复活)。

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

祝你好运

【讨论】:

    【解决方案2】:

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

    而且,除非 myInstance 是用 assign 声明的,否则你不会想调用 self.myInstance = [[AClass alloc] init] 你最好使用 self.myInstance = [[[AClass alloc] init] autorelease]

    【讨论】:

      【解决方案3】:

      注意使用

      myInstance = nil
      

      而不是

      self.myInstance = nil
      

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

      【讨论】:

        【解决方案4】:

        这取决于您在接口中定义的属性。例如,如果您定义保留属性:

        @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 的完整属性指南。

        【讨论】:

        【解决方案5】:

        实际使用

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

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

        【讨论】:

          【解决方案6】:
          ... = self.myInstance
          

          self.myInstance = ...
          

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

          如果是保留属性,子例程可能会使用保留计数。如果你自己做 getter 和 setter,你可以让他们控制你家的灯,在非零设置时打开它们,在设置为零或零时关闭灯。甚至不需要一个名为“instance”的支持变量,可以通过以下方式设置:

          instance = ...
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-02-12
            • 1970-01-01
            • 2011-06-26
            • 2010-10-22
            • 1970-01-01
            • 1970-01-01
            • 2015-07-03
            相关资源
            最近更新 更多