2

保持サイクルと「このブロックで自己を強力にキャプチャすると、保持サイクルにつながる可能性があります」という警告を回避するために、ブロック内のすべてのオブジェクトに次のようなものを追加しました

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

///the block code with some examples
 up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

       [weakSelf aMethodInTheController];
       [weakLabel setHidden:NO];
       [weakArray addObject:@"something"];

 };

弱い参照を使用すると、保持サイクルの警告は消えますが、設定する必要がある nnstring をブロック内に導入すると問題が発生します

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

NSString *__weak weakString=AString;

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

   [weakSelf aMethodInTheController];
   [weakLabel setHidden:NO];
   [weakArray addObject:@"something"];
   weakString=@"atext";

 };

このようにして、「変数は割り当てられません(_ブロックタイプ指定子がありません)」というエラーが表示されるため、「_block」を追加しまし

MyViewController *__weak weakSelf= self;
NSMutableArray *__weak weakArray=AnArray;
UILabel *__weak weakLabel=ALabel;

NSString *__weak weakString=AString;
__block NSString *BlockString =  weakString;    

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

[weakSelf aMethodInTheController];
[weakLabel setHidden:NO];
[weakArray addObject:@"something"];
 BlockString=@"atext";

 };

このようにして、少なくともブロック内に入るまでは、すべてが正しく機能しているようです... 元の Astring 変数は、viewController の .h で定義されています。後でその値にアクセスする必要があります。値は常に nil です。@"atext" を BlockString に割り当てても、元の Astring 変数に値が設定されませんか? viewController の .h に設定された変数の値を、警告を受けずにブロックを終了せずに設定するにはどうすればよいですか?

4

2 に答える 2

1

と が View Controller の ivar であると仮定するとaLabelanArray本当に心配するのは だけweakSelfであり、そこからすべての ivar とプロパティを参照します。また、ivar を効果的に逆参照しているため、ブロック内に強い参照が存在します (弱い変数を逆参照できないため)。aLabelしたがって、 、anArray、 anaStringが ivarであると仮定すると、次のようになります。

MyViewController *__weak weakSelf = self;

///the block code with some examples
up2.completionBlock = ^(NSDictionary *headers, NSString *responseString) { 

    MyViewController *strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf aMethodInTheController];
        [strongSelf->aLabel setHidden:NO];
        [strongSelf->anArray addObject:@"something"];
        strongSelf->aString = @"something else";
    }
};

率直に言って、私は ivars の間接参照が好きではなく、むしろプロパティを使用したいと思っています (いくつかの理由から)。しかし、どちらも機能します。

このパターンの例については、「ARC リリース ノートへの移行」の「強力な参照サイクルを回避するためにライフタイム修飾子を使用する」セクションを参照してください(特に、「重要なサイクル」について説明している少し後で)。

于 2013-09-27T15:54:02.593 に答える