阻止可能导致保留周期 [英] block is likely to lead a retain cycle

查看:76
本文介绍了阻止可能导致保留周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为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

它似乎正常工作,但是当我调用它时(如下面的代码片段所示),我收到警告:

it seems to work properly but when I call it (as shown in the following snippet) I get a warning:

区块可能会导致保留周期

block is likely to lead a retain cycle

[_queue addAsynchronousOperationWithBlock:^(block signal) {
        [self foo:nil];
         signal();
}];

foo是使用此类别的类的方法.

foo is a method of the class that uses this category.

addOperationWithBlock:相同的代码(来自NSOperationQueue)不会显示警告:

The same code with addOperationWithBlock: (from NSOperationQueue) doesn't show the warning:

[_queue addOperationWithBlock:^ {
        [self foo:nil];
}];

我真的不明白. 特别是我不明白的是: 在这两种情况下,我都应该实际使用弱指针吗?万一我不使用弱指针,这两个代码片段实际上会带来一个保留周期吗?

I really don't understand it. Particularly what I don't understand is: should I actually use the weak pointer in both the cases? will actually the two snippet bring to a retain cycle in case I don't use the weak pointer?

推荐答案

摘录其他人在这里写的内容:

To distill what others have written here:

  1. 两个代码示例均未创建此类持久的保留周期 会束缚记忆.
  2. Xcode抱怨您的addAsynchronousOperationWithBlock方法,因为它的名称可疑.它不会抱怨addOperationWithBlock,因为它对addOperationWithBlock有特殊的了解,可以克服怀疑.
  3. 要摆脱警告,请使用__weak(请参阅jszumski和matt的答案),或者将addAsynchronousOperationWithBlock重命名为不以"add"或"set"开头.
  1. Neither code example creates a long-lasting retain cycle of the sort that will strand memory.
  2. Xcode complains about your addAsynchronousOperationWithBlock method because it has a suspicious name. It doesn't complain about addOperationWithBlock because it has special knowledge about addOperationWithBlock that overrides its suspicions.
  3. To get rid of the warning, use __weak (see the answers by jszumski and matt) or rename addAsynchronousOperationWithBlock to not start with "add" or "set".

详细说明以下内容:

  1. 如果self拥有_queue,则您的保留周期将很短. self将拥有_queue,后者将拥有这些块,而调用[self foo:]的块将拥有self.但是一旦这些块运行完毕,_queue将释放它们,并且循环将被中断.

  1. If self owns _queue, you will have a short-lived retain cycle. self will own _queue, which will own the blocks, and the block that calls [self foo:] will own self. But once the blocks have finished running, _queue will release them, and the cycle will be broken.

已将静态分析器编程为怀疑以"set"和"add"开头的方法名称.这些名称表明该方法可能会永久保留传递的块,可能会创建一个永久的保留周期.因此,有关您的方法的警告.它并没有抱怨-[NSOperationQueue addOperationWithBlock:],因为有人知道NSOperationQueue在运行它们之后会释放它们,因此有人告诉他们不要这么做.

The static analyzer has been programmed to be suspicious of method names starting with "set" and "add". Those names suggest that the method may retain the passed block permanently, possibly creating a permanent retain cycle. Thus the warning about your method. It doesn't complain about -[NSOperationQueue addOperationWithBlock:] because it's been told not to, by someone who knows that NSOperationQueue releases blocks after running them.

如果使用__weak,则分析仪不会抱怨,因为不会有保留周期的可能性.如果重命名方法,分析器将不会抱怨,因为它没有任何理由怀疑您的方法永久保留传递给它的块.

If you use __weak the analyzer won't complain because there won't be the possibility of a retain cycle. If you rename your method the analyzer won't complain because it won't have any reason to suspect your method of permanently retaining the block passed to it.

这篇关于阻止可能导致保留周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆