【问题标题】:Setting an object nil versus release+realloc设置对象 nil 与 release+realloc
【发布时间】:2010-10-12 05:31:31
【问题描述】:

这不是垃圾收集环境

我有一个类实例变量,在我运行时的某个时刻,我需要使用与最初构建时不同的数据集重新初始化。

假设地说,如果我有一个NSMutableArrayNSMutableDictionary,那么执行以下操作会更有效吗:

[myArr release];
myArr  = [[NSMutableArray alloc] init....];

或者只是,

myArr = nil;

myArr 是否会释放对象并让我没有指向内存中存储的指针,以便我可以重用 myArr?

【问题讨论】:

    标签: iphone objective-c ios cocoa-touch cocoa


    【解决方案1】:

    如果您自己执行myArr=nil;,那么您就丢失了可以向其发送release 消息的指针。 release 你的对象没有魔法。

    而且,正如 Georg 所说,由于无法释放您的对象,该内存已“泄漏”。

    【讨论】:

      【解决方案2】:

      第一个代码块很好。但是,第二个块并没有给您留下可以使用的数组,因此还不够。半改正那个块,我想你的意思是:

      myArr = nil;
      myArr = [[NSMutableArray alloc] init....];
      

      但是,这也不能实现您想要的,因为您没有发布 myArr。如果你已经为 myArr 合成了一个 setter,那么你可以通过使用 setter (self.myArr) 而不是直接访问指针 (myArr) 来获得你想要的从设置到 nil 的释放行为。完全纠正你的第二个块:

      self.myArr = nil;
      myArr = [[NSMutableArray alloc] init....];
      

      现在我们有了等效的代码示例,一个使用带有 nil 的 setter 来释放,另一个不使用。它们是一样的。

      如果在这些示例中 myArr 是一个可变数组,最有效的方法是使用 removeAllObjects,避免所有释放内存的工作只是为了收回它:

      [myArr removeAllObjects];
      

      【讨论】:

      • Re #2:此外,您还可以将 setter 与新数组一起使用(传递一个自动释放的数组,[NSMutableArray array]),然后使用数组访问器来填充它。 developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… 当然,如果您要立即填充新数组,那么在局部变量中使用新数组执行此操作会更有效,然后将属性设置为完成的数组。而且这两种方法都不需要先将属性设置为nil
      【解决方案3】:

      如果你想要重置 NSMutableArray/NSMutableDictionary 的内容,你也可以调用 removeAllObjects 并且你有一个新的数组/字典可以使用。

      【讨论】:

        【解决方案4】:

        您可以使用属性并获得几乎您想要的语法,而不会出现内存泄漏。

        使用此语法声明数组

        @property (readwrite, retain) NSMutableArray *myArray;
        

        然后像这样重新初始化它:

        [self setMyArray:[NSMutableArray array]];
        

        【讨论】:

        • 或者使用点属性语法:self.myArray = [NSMutableArray array];
        • 因为 myArray 指向一个可变对象,更好的形式是 @property(readwrite, copy)NSMutableArray *myArray
        【解决方案5】:

        如果您使用的是 Mac OS,而不是 iPhone OS,我会说这取决于垃圾收集器是否被激活:

        • 使用 GC:使用 myArr = nil;
        • 没有 GC:使用[myArr release];

        不幸的是,在 iPhone 上,没有垃圾回收,所以如果你不想内存泄漏,你必须在不再需要时释放你的对象。

        【讨论】:

        • 是的,你是对的。我太专注于 Mac OS...我的答案已更新。
        • 您甚至不需要将其设置为 nil,因为这主要发生在 dealloc 代码中,当收集了包含所有链接的上层对象时。
        【解决方案6】:

        实现这种差异的一种方法可能是:将对对象的引用设置为 nil 对对象没有任何作用,它只会对引用做一些事情。

        “释放对象”不是“什么都没有”,所以它不会那样做。 :) 在垃圾收集语言中,它可能会作为删除引用的副作用,但在 Objective C 中它不是这样工作的。

        【讨论】:

          猜你喜欢
          • 2011-12-30
          • 2011-11-13
          • 1970-01-01
          • 1970-01-01
          • 2011-10-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-21
          相关资源
          最近更新 更多