2

我在接口上声明了这样的 ivar:

BOOL controllerOK;

我必须在一个块内使用这个 ivar,该块本身位于一个块中。就像是

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

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

在此块中强烈捕获自我可能会导致保留循环

对于 if (controllerOK) 行。

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

我该如何解决?

4

6 回答 6

2

这应该有效:

__weak id this = self;
myBlockl = ^(){
  [self presentViewController:controller
    animated:YES
    completion:^(){
      if (this->controllerOK)
        [this doStuff];
      }];
};
于 2012-11-26T04:50:39.783 回答
1

controllerOK隐式编译为self->controllerOK因为它需要通过 self. 正因为如此,它 “那些块问题之一”,尽管在这种情况下只是一个简单的BOOL变量就可以了。

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

我把它放在_weak那里是因为即使你修​​复了 的警告消息controllerOK,你也会再次得到它[self doStuff]

于 2012-11-26T04:52:43.580 回答
0

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

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

__weak id weakSelf = self;

正如 rmaddy 所观察到的,引用 ivarcontrollerOK也会生成一个强引用循环。您可以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];
                         }];
};
于 2012-11-26T04:39:02.057 回答
0

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

于 2012-11-26T04:53:08.290 回答
-1

你能这样试试吗

myBlockl = ^(){

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

我对块不是很熟悉,但它对我有用......

于 2012-11-26T04:41:39.813 回答
-1

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

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

于 2012-11-26T05:01:33.237 回答