我为NSOperationBlock
编写了以下类别
@implementation NSOperationQueue (Extensions)
-(void)addAsynchronousOperationWithBlock:(void (^)(block))operationBlock
{
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
block signal = ^ {
dispatch_semaphore_signal(semaphore);
};
[self addOperationWithBlock:^{
operationBlock(signal);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(semaphore);
}];
}
@end
它似乎正常工作,但是当我调用它时(如下面的片段所示),我会收到一个警告:
块可能会导致保留周期。
[_queue addAsynchronousOperationWithBlock:^(block signal) {
[self foo:nil];
signal();
}];
foo
是使用此类别的类的方法。
与addOperationWithBlock:
相同的代码(来自NSOperationQueue
)没有显示警告:
[_queue addOperationWithBlock:^ {
[self foo:nil];
}];
我真的不明白。特别是我不明白的是:在这两种情况下,我真的应该使用弱指针吗?如果我不使用弱指针,这两个片段实际上会带来一个保留周期吗?
发布于 2013-05-13 14:13:32
把其他人在这里写的东西提取出来:
addAsynchronousOperationWithBlock
方法,因为它有一个可疑的名称。它不抱怨addOperationWithBlock
,因为它对addOperationWithBlock
有特殊的了解,它可以克服它的怀疑。__weak
(请参阅jszumski和matt的答案)或将addAsynchronousOperationWithBlock
重命名为不以"add“或"set”开头。详细说明以下几点:
self
拥有_queue
,那么您将有一个短暂的保留周期。self
将拥有_queue
,它将拥有这些块,调用[self foo:]
的块将拥有self
。但是,一旦这些块运行完毕,_queue
就会释放它们,并且这个循环将被打破。-[NSOperationQueue addOperationWithBlock:]
,因为有人告诉它不要这样做,因为有人知道NSOperationQueue
在运行它们之后释放块。__weak
,分析器不会抱怨,因为不存在保留周期的可能性。如果您重命名您的方法,分析器不会抱怨,因为它没有任何理由怀疑您永久保留传递给它的块的方法。发布于 2013-05-08 21:43:02
当您在块中使用self
时,它会被块捕获,并可能导致保留周期。当self
(或它具有强引用的内容)对块具有强引用时,就会发生循环。要避免潜在的循环,请声明一个弱指针并在块中使用该指针:
YourClassName * __weak weakSelf = self;
[_queue addAsynchronousOperationWithBlock:^(block signal) {
[weakSelf foo:nil];
}];
发布于 2013-05-09 02:19:44
jszumski的回答在本质上是正确的,但重要的是要使“弱我”舞蹈的形式正确。表格(基于他的代码)是:
YourClassName * __weak weakSelf = self;
[_queue addAsynchronousOperationWithBlock:^(block signal) {
YourClassName * strongSelf = weakSelf;
if (strongSelf)
[weakSelf foo:nil];
}];
因此,我们通过一个强引用捕获weakSelf
。如果不这样做,weakSelf
可能会在您使用它的过程中消失(因为您对它的引用很弱)。
请看我的关于舞蹈的书,以及其他你可以做的关于块引起的潜在保留周期的事情:
https://stackoverflow.com/questions/16450675
复制相似问题