伊瓦尔在两个街区内

时间:2012-11-26 04:33:43

标签: iphone ios ipad objective-c-blocks

我在界面上声明了这样的ivar:

BOOL controllerOK;

我必须在一个块中使用这个ivar。像

这样的东西
myBlockl = ^(){
  [self presentViewController:controller
    animated:YES
    completion:^(){
      if (controllerOK)
        [self doStuff];
      }];
};

如果我尝试这样做,我会看到一个警告:

  

在此区块中强烈捕获自我可能会导致保留周期

表示if(controllerOK)行。

这似乎不是在块启动之前使用__unsafe_unretained创建另一个变量的那些块问题之一。首先是因为该指令不能与BOOL一起使用,因为必须在块内的运行时测试ivar controllerOK。另一个问题是块本身是在接口上声明的,因此它将在创建它的上下文之外使用。

我该如何解决?

6 个答案:

答案 0 :(得分:2)

这应该有效:

__weak id this = self;
myBlockl = ^(){
  [self presentViewController:controller
    animated:YES
    completion:^(){
      if (this->controllerOK)
        [this doStuff];
      }];
};

答案 1 :(得分:1)

controllerOK隐式编译为self->controllerOK,因为它需要通过 self访问其内存位置。正因为如此, &#34;其中一个阻止了问题&#34; ,尽管在​​这种情况下只需要一个简单的BOOL变量。< / p>

__weak typeof(self) weakSelf = self;
myBlockl = ^(){
    BOOL isControllerOK = controllerOK;
    [self presentViewController:controller animated:YES completion:^(){
        if (isControllerOK)
        {
            [weakSelf doStuff];
        }
    }];
};

我将_weak放在那里,因为即使您修复了controllerOK的警告消息,您也会在[self doStuff]

中再次获取该警告消息

答案 2 :(得分:0)

您需要使用weak引用替换对象的引用。

典型的解决方法是声明一个局部变量:

__weak id weakSelf = self;

正如rmaddy观察到的那样,提到一个ivar,controllerOK,也会产生一个强大的参考周期。您可以将BOOL controllerOK ivar替换为对象:

NSNumber *controllerOK;

然后您可以使用weak引用,例如以下内容:

controllerOK = @YES;

__weak typeof(self) weakSelf = self;
__weak NSNumber *weakControllerOk = controllerOK;

myBlockl = ^(){
    [weakSelf presentViewController:controller
                           animated:YES
                         completion:^(){
                             if ([weakControllerOk boolValue])
                                 [weakSelf doStuff];
                         }];
};

答案 3 :(得分:0)

问题可能在于您实际上并未引用实际代码。我尝试了你的代码,它在ARC下编译,没有任何警告。但我必须稍微修改它,因为你声明一个块的语法是错误的。因此,您显然没有复制和粘贴您的实际代码。如果您没有展示给您带来麻烦的真实代码,那么人们会浪费时间帮助您。

答案 4 :(得分:-1)

你能尝试这样吗

myBlockl = ^(){

    [self presentViewController:controller
                       animated:YES
                     completion:^(BOOL isFinished){
                                if (isFinished == controllerOK)
                                      [self doStuff];
                                  }];
};

我对积木不太熟悉,但它对我有用.....

答案 5 :(得分:-1)

不幸的是,唯一有效的解决方案是将BOOL controllerOK转换为非原子属性,分配然后在块内使用它。

我已经测试了您在此处发布的所有解决方案,但没有成功。