1
#import "ViewController.h"

@implementation ViewController

int tnt=1;

-(void)myMethod{

    void(^blk)(void) = ^(void){
        tnt = 3+1;
        NSLog(@"tnt=>%d", tnt);
    };

    blk();
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self myMethod];
}

変数 tnt は外側にありますが、ブロックの内側では完全に正常に機能しています。myMethod 内で tnt 変数を宣言すると、__block に必要なエラーが発生し始めます。

どちらの場合も、tnt 変数はブロックの外にあります。Apple docs には、外部の変数には __block ストレージ タイプが必要であるとも書かれています。tnt が myMethod の外で宣言されている場合に機能するのはなぜですか。

4

2 に答える 2

1

それは範囲に関連していると思います。ドキュメントから:

__block ストレージ修飾子で宣言された囲んでいるレキシカル スコープに対してローカルな変数は、参照によって提供されるため、変更可能です。同じ囲みレキシカルスコープ内で定義された他のブロックを含め、すべての変更は囲んでいるレキシカルスコープに反映されます。これらについては、「__block ストレージ タイプ」で詳しく説明しています。</p>

レキシカル スコープの外に置く場合は、修飾子int tnt=1;を使用する必要はないと思います。ここ__blockに例があります。以下も読むことができます。

__block 変数は、変数のレキシカル スコープと、変数のレキシカル スコープ内で宣言または作成されたすべてのブロックおよびブロック コピーとの間で共有されるストレージに存在します。したがって、フレーム内で宣言されたブロックのコピーがフレームの最後を超えて存続する場合 (たとえば、後で実行するためにどこかでキューに入れられることによって)、ストレージはスタック フレームが破棄されても存続します。特定のレキシカル スコープ内の複数のブロックは、共有変数を同時に使用できます。

int tnt=1;はレキシカル スコープ外で宣言されているため、スタックが破棄されても存続します。

于 2012-11-12T11:54:52.183 に答える
0

グローバル変数をキャプチャする必要はありません。

于 2012-11-12T19:22:34.230 に答える