2

インターフェイスで宣言された次のような ivar があります。

BOOL controllerOK;

ブロック内に存在するブロック内でこの ivar を使用する必要があります。何かのようなもの

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

そうしようとすると、次の警告が表示されます。

このブロックで自己を強くキャプチャすると、保持サイクルが発生する可能性があります

if (controllerOK) 行の場合。

これは、ブロックの開始前に __unsafe_unretained を使用して別の変数を作成するブロックの問題の 1 つではないようです。1 つ目は、この命令を BOOL で使用できないため、2 つ目は、ivar controllerOK をブロック内の実行時にテストする必要があるためです。もう 1 つの問題は、ブロック自体がインターフェイスで宣言されているため、ブロックが作成されているコンテキストの外で使用されることです。

どうすれば解決できますか?

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てメモリ位置にアクセスする必要があるため、暗黙的に as としてコンパイルされます。そのため、これ「これらのブロックの問題の 1 つ」ですが、この場合は単純な変数だけで十分です。 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 が観察したように、ivar を参照するとcontrollerOK、強力な参照サイクルも生成されます。BOOL controllerOKivar をオブジェクトに置き換えることができます。

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 に答える