如何在ARC下使用块完成处理程序释放对象?

zou*_*oul 9 memory-management objective-c objective-c-blocks automatic-ref-counting

这是我的代码中分配对象的常见模式,让它使用完成处理程序执行一些操作并在处理程序中释放它:

LongOperation *foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
    // run some code and then:
    [foo autorelease];
}];
Run Code Online (Sandbox Code Playgroud)

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

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

[self setFoo:[[LongOperation alloc] init]];
[foo runWithCompletion:^{
    // run some code and then:
    [self setFoo:nil];
}];
Run Code Online (Sandbox Code Playgroud)

......但代码不再是可重入的.

Jas*_*oco 5

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

__block LongOperation* foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
  // do some things
  foo = nil;
}];
Run Code Online (Sandbox Code Playgroud)

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