【问题标题】:Need to retain an NSArray twice to avoid a crash - why?需要保留 NSArray 两次以避免崩溃 - 为什么?
【发布时间】:2011-05-04 05:58:22
【问题描述】:

我有一个运行可靠的复杂应用程序,但我很困惑为什么我需要保留一个特定的 NSArray ('sources') 两次 以防止崩溃(尽管在控制台,但应用程序崩溃并返回跳板)。

代码的 sn-p 包含在下面。有太多代码无法全部粘贴,但我保证没有显式调用来释放数组。 'sources' 是一个实例变量。

如果我只保留数组一次(或根本不保留),我会崩溃。有两个retain,App非常稳定。

NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Sources" ofType:@"plist"];

sources  = [[NSArray arrayWithContentsOfFile:plistPath] autorelease];

[sources retain];
[sources retain];

对我为什么需要保留这个数组两次的想法表示赞赏。提前致谢。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:
    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Sources" ofType:@"plist"];
    
    sources  = [[NSArray alloc] initWithContentsOfFile:plistPath];
    

    【讨论】:

      【解决方案2】:

      那是因为 arrayWithContentsOfFile: 返回一个自动释放的数组给你。在这个数组上调用 autorelease 将在当前事件运行循环结束时释放它两次。

      【讨论】:

        【解决方案3】:

        有一个显式调用来释放数组。 autoreleaserelease 一样明确——它只是稍后发生。不仅如此,首先自动释放数组是错误的,因为你不拥有它。需要一个retain 来声明阵列的所有权。第二个通过平衡autorelease 的错误使用来防止崩溃。

        【讨论】:

        • 感谢 Chuck,以及其他所有人的回复,非常感谢。
        【解决方案4】:

        放弃工厂方法的自动释放。这就是为什么您需要第二次保留。

        【讨论】:

          【解决方案5】:

          您正在使用+arrayWithContentsOfFile:,它返回一个自动释放的对象,然后再次自动释放它。拨打-autorelease 的电话,您会没事的。你可以这样重写它:

          sources  = [[NSArray arrayWithContentsOfFile:plistPath] retain];
          

          【讨论】:

          【解决方案6】:

          这与自动释放有关吗?我不明白为什么会这样:它应该是自动释放的工厂方法。虽然我不知道添加额外自动释放的后果是什么,但如果将它与保留之一一起取出,可能值得看看会发生什么。

          【讨论】:

          • Autorelease 显然是不正确的,但有人知道它为什么会导致问题吗?我会认为一旦最近的自动释放池知道该阵列,它会在耗尽时发送一个释放,但经常发送自动释放。显然不是,但有人知道为什么吗?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-03-23
          • 2015-09-06
          • 2021-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多