【问题标题】:How do I release an object with a block completion handler under ARC?如何在 ARC 下使用块完成处理程序释放对象?
【发布时间】:2012-01-04 08:17:17
【问题描述】:

在我的代码中分配一个对象是一种常见的模式,让它用一个完成处理程序做一些事情并在处理程序中释放它:

LongOperation *foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
    // run some code and then:
    [foo autorelease];
}];

这工作得很好,但是当我尝试将代码转换为 ARC 时,Xcode 正确地抱怨它不能简单地从块中删除 autorelease,因为这会使 foo 对象在离开后被释放范围。

那么在 ARC 下写这种模式有什么好的方法呢?我可以为foo 引入一个实例变量:

[self setFoo:[[LongOperation alloc] init]];
[foo runWithCompletion:^{
    // run some code and then:
    [self setFoo:nil];
}];

…但代码将不再可重入。

【问题讨论】:

    标签: objective-c memory-management automatic-ref-counting objective-c-blocks


    【解决方案1】:

    在大多数情况下,它应该可以工作(即,如果在 foo 中引用了 self ,则 foo 将持续足够长的时间来满足该代码,然后再离开)。如果弱引用存在问题,并且 foo 看起来应该消失但直到处理程序运行后才应该消失,您可以执行以下操作:

    __block LongOperation* foo = [[LongOperation alloc] init];
    [foo runWithCompletion:^{
      // do some things
      foo = nil;
    }];
    

    请注意,这与这种模式相反,它导致对象 /not/ 在托管内存规则下被捕获。

    【讨论】:

    • 这并没有回答问题是当包含 foo 的上下文早已消失时该怎么办。使用此解决方案,调用 [foo runWithCompletion:] 的堆栈帧必须阻塞,直到运行完成或冒着堆栈粉碎机的风险。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2023-03-19
    • 2012-10-01
    • 1970-01-01
    • 2012-05-04
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多