【问题标题】:retainCount in blocks show extrange behavior块中的 retainCount 显示异常行为
【发布时间】:2011-03-08 13:29:45
【问题描述】:

我在课堂上得到了这个代码:

- (void)cancel {
    if (_cancelBlock)
        _cancelBlock();
}
- (void)overrideCancelWithBlock:(void(^)(void))cancelBlock {
    [_cancelBlock release];
    NSLog(@"AsyncOperation-overrideCancelWithBlock-[cancelBlock retainCount]=%lu (before)", [cancelBlock retainCount]);
    _cancelBlock = [[cancelBlock copy] retain];
    NSLog(@"AsyncOperation-overrideCancelWithBlock-[_cancelBlock retainCount]=%lu (after)", [_cancelBlock retainCount]);
}

- (void)dealloc
{
    NSLog(@"AsyncOperation-dealloc-[_cancelBlock retainCount]=%lu (before)", [_cancelBlock retainCount]);
    [_cancelBlock release];
    NSLog(@"AsyncOperation-dealloc-[_cancelBlock retainCount]=%lu (after)", [_cancelBlock retainCount]);
    [super dealloc];
}

这个 NSLog() 的输出是:

 AsyncOperation-overrideCancelWithBlock-[cancelBlock retainCount]=1 (before)
 AsyncOperation-overrideCancelWithBlock-[_cancelBlock retainCount]=1 (after)
 AsyncOperation-dealloc-[_cancelBlock retainCount]=1 (before)
 AsyncOperation-dealloc-[_cancelBlock retainCount]=1 (after) 

copy 方法的文档是这样说的:

特别注意事项

如果您使用的是托管内存(不是 垃圾收集),这种方法 保留之前的新对象 退回它。调用者 方法,但是,负责 释放返回的对象。

所以。 NSLog() 的输出总是为retainCount 显示相同的值?

【问题讨论】:

    标签: objective-c objective-c-runtime objective-c-blocks


    【解决方案1】:

    documentationretainCount 是这样说的:

    重要提示:此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存了任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。

    要了解您必须遵守的内存管理基本规则,请阅读“内存管理规则”。要诊断内存管理问题,请使用合适的工具:

    LLVM/Clang 静态分析器通常甚至可以在您运行程序之前发现内存管理问题。
    Instruments 应用程序中的 Object Alloc 工具(请参阅 Instruments 用户指南)可以跟踪对象分配和销毁。
    Shark(请参阅 Shark 用户指南)还分析内存分配(在程序的许多其他方面)。

    回答你的问题:只有苹果可能知道为什么此时的 retainCount 是这样的。

    【讨论】:

    • fluchtpunkt 是正确的。只要您遵循正确的内存管理指南,就不必担心。检查任何对象的保留计数也被认为是“不好的做法”,因为它们通常会产生误导。
    【解决方案2】:
    _cancelBlock = [[cancelBlock copy] retain];
    

    这会过度保留块;只需 - 复制它。


    由于 Block 可以在运行时根据所采取的操作更改形式,并在编译时根据实现细节更改类型,因此各种 Block 类通常将 retainCount 视为废话生成器。在某些情况下,这意味着总是返回 1。

    请注意,在所有情况下,retainCount 为零在逻辑上都是不可能的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      相关资源
      最近更新 更多