关于Objective C:保留以块为单位的计数显示奇怪的行为

retainCount in blocks show extrange behavior

我在一个班上得到了以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (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()的输出是:

1
2
3
4
 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方法的文档说:

Special Considerations

If you are using managed memory (not
garbage collection), this method
retains the new object before
returning it. The invoker of the
method, however, is responsible for
releasing the returned object.

所以。 NSLog()的输出始终为retainCount

显示相同的值


1
_cancelBlock = [[cancelBlock copy] retain];

那保留了块;只需-复制它。

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

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


retainCount的文档中说:

Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

To understand the fundamental rules of memory management that you must abide by, read a€?Memory Management Rulesa€?. To diagnose memory management problems, use a suitable tool:

The LLVM/Clang Static analyzer can typically find memory management problems even before you run your program.
The Object Alloc instrument in the Instruments application (see Instruments User Guide) can track object allocation and destruction.
Shark (see Shark User Guide) also profiles memory allocations (amongst numerous other aspects of your program).

要回答您的问题:只有苹果公司可能知道为什么此时的keepCount如此。