为什么这个GCD示例代码似乎不正确地释放了一个对象?

时间:2012-06-05 19:38:03

标签: objective-c multithreading memory-management grand-central-dispatch

wikipedia example作者release对象stats,当它尚未分配,复制或保留时。这是一个错误还是我不理解的东西?

- (IBAction)analyzeDocument:(NSButton *)sender
{
  dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSDictionary *stats = [myDoc analyze];
    dispatch_async(dispatch_get_main_queue(), ^{
      [myModel setDict:stats];
      [myStatsView setNeedsDisplay:YES];
      [stats release];
    });
  });
}

3 个答案:

答案 0 :(得分:2)

这是一个错误,或者正确记录analyze将对象的所有权返回给调用者。如果stats未发布错误,那么代码示例正在使用违反Apple's memory management rules所有权的约定。

  

内存管理规则,有时也称为所有权   策略,帮助您在Objective-C代码中显式管理内存。

     

您拥有通过为其分配内存或复制而创建的任何对象   它。
  相关方法:alloc,allocWithZone:,copy,copyWithZone:,   mutableCopy,mutableCopyWithZone:

应该返回所有权的另一个前缀是类方法+new。例如。 [MyDocClass newAnalysis];

答案 1 :(得分:2)

这只是一个示例cooked up by John Siracusa来演示GCD如何轻松地将长时间运行的任务放入后台,但是,是的,它有两个问题之一,一个是内置约定,另一个是实际错误

虚构的analyze方法可能会返回拥有的引用。这违反了Cocoa约定,未命名为newallocreleasecopy...的方法通常不会返回此类引用,但是如果文档明确表明它确实存在,并且实际上没有办法解决它,它就可以了。在这种情况下,将release发送到stats是必要的,以避免内存泄漏。 (如果这是真正的代码,重命名方法将是一个好主意,可能使用在CoreFoundation中用于表示返回拥有引用的create。)

但是,如果analyze遵循约定并返回非拥有引用,那么您是对的,将release发送到stats是不正确的,最终会导致崩溃。< / p>

答案 2 :(得分:1)

很可能analyze正在返回一个保留计数为1的字典,这就是需要release的原因。