It’s a common pattern in my code to allocate an object, let it do some stuff with a completion handler and release it in the handler:
这是我的代码中分配对象的常见模式,让它使用完成处理程序执行一些操作并在处理程序中释放它:
LongOperation *foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
// run some code and then:
[foo autorelease];
}];
This works fairly well, but when I attempt to convert the code to ARC, Xcode rightly complains that it can’t simply drop the autorelease
from the block, since that would make the foo
object get deallocated after leaving the scope.
这工作得相当好,但是当我尝试将代码转换为ARC时,Xcode正确地抱怨它不能简单地从块中删除自动释放,因为这会使foo对象在离开作用域后被释放。
So what’s a good way to write this kind of pattern under ARC? I could introduce an instance variable for foo
:
那么在ARC下编写这种模式的好方法是什么?我可以为foo引入一个实例变量:
[self setFoo:[[LongOperation alloc] init]];
[foo runWithCompletion:^{
// run some code and then:
[self setFoo:nil];
}];
…but the code would not be re-entrant anymore.
......但代码不再是可重入的。
1 个解决方案
#1
4
In most cases, it should work (i.e., if anything references self inside of foo, foo will last long enough to satisfy that code before going away). If there are issues with weak references and such that foo looks like it should go away but shouldn't until after the handler runs, you can do something like:
在大多数情况下,它应该工作(即,如果有任何内容在foo内部引用self,foo将持续足够长的时间以满足该代码,然后离开)。如果存在弱引用的问题,并且foo看起来应该消失,但是在处理程序运行之后不应该执行以下操作:
__block LongOperation* foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
// do some things
foo = nil;
}];
Note this is kind of the opposite of this pattern which causes the object /not/ to be captured under managed memory rules.
请注意,这与此模式相反,导致在受管内存规则下捕获对象/不/。
#1
4
In most cases, it should work (i.e., if anything references self inside of foo, foo will last long enough to satisfy that code before going away). If there are issues with weak references and such that foo looks like it should go away but shouldn't until after the handler runs, you can do something like:
在大多数情况下,它应该工作(即,如果有任何内容在foo内部引用self,foo将持续足够长的时间以满足该代码,然后离开)。如果存在弱引用的问题,并且foo看起来应该消失,但是在处理程序运行之后不应该执行以下操作:
__block LongOperation* foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
// do some things
foo = nil;
}];
Note this is kind of the opposite of this pattern which causes the object /not/ to be captured under managed memory rules.
请注意,这与此模式相反,导致在受管内存规则下捕获对象/不/。