【问题标题】:Why does block object not dealloc the same way NSObject does?为什么块对象不像 NSObject 那样释放?
【发布时间】:2014-08-27 16:29:41
【问题描述】:

这是一个说明问题的代码sn-p

__weak id ptr = nil;
__weak id ptr2 = nil;
@autoreleasepool {
    void (^block)(void) = [^{
        NSLog(@"hahaha");
    } copy];
    block();
    [[(id)block rac_willDeallocSignal] subscribeCompleted:^{
        NSLog(@"block will dealloc");
    }];
    ptr = block;
    int blockRetainCount = CFGetRetainCount((__bridge CFTypeRef)block);

    NSObject *obj = [[NSObject alloc] init];
    [obj.rac_willDeallocSignal subscribeCompleted:^{
        NSLog(@"Obj dealloc");
    }];
    ptr2 = obj;
    int objRetainCount = CFGetRetainCount((__bridge CFTypeRef)obj);
    NSLog(@"oK");
}
NSLog(@"after pool %@ %@" , ptr, ptr2);

当我运行这个 sn-p 时,我会看到 Obj dealloc 打印到控制台,但不是 block will dealloc。在自动释放池之后,我还将看到 ptr 仍然包含对块的有效引用,而 ptr2 已按预期正确重置为 nil。为什么会有这种差异?块什么时候被解除分配?

【问题讨论】:

    标签: ios objective-c memory-management objective-c-blocks


    【解决方案1】:

    应该说服你不要尝试这样的事情的多个问题:

    第一,CFGetRetainCount 不能保证在 ARC 存在的情况下返回任何有意义的东西。

    第二,完全不能保证一个块使用保留计数。不捕获任何变量的块被分配为静态变量;复制、保留等对它们根本不做任何事情,它们永远不会被分配或释放。

    第三,不能保证任何块在被释放时都会调用 dealloc。并且不保证它会在下一个操作系统或 iOS 版本中发生。

    【讨论】:

    • 我认为我的关键词是 Blocks that don't capture any variables are allocated as static variables; copy, retain and so on do nothing at all to them, and they are never allocated or deallocated. 会测试一下。
    • 确实!如果我将块定义更改为 ``` NSString *mystr = @"hahaha"; void (^block)(void) = [^{ NSLog(@"%@", mystr); } 复制]; ``` 然后ptr 在自动释放池的末尾设置为nilCFGetRetainCountdealloc 钩子只是拼命尝试理解为什么块没有被释放:)
    • CFGetRetainCount() 不能保证返回任何有意义的东西。
    猜你喜欢
    • 2015-07-18
    • 2021-12-09
    • 2015-07-07
    • 2011-11-18
    • 2023-02-03
    • 2010-10-21
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多