GCDを使用したObjective-Cで次の問題が発生しました。理解できません。
次の方法を使用して、648個のタイルの計算を行っています。最初に処理するタイルの順序は、変数「pi」を設定するアルゴリズムによって指定されます。変数「loaded」はこのコンテキストではグローバルであり、0から始まり、正しく647まで上がります。
ブロックを使用しない場合、すべてが完全に機能します。
while (loaded < [self.tiles count]) {
long pi = /* tricky way to calculate the position index to set */;
NSLog(@"loaded: %d", loaded);
// Do this in a separate thread
dispatch_async(loader, ^{
NSLog(@"loaded ->: %d", loaded);
[self.tiles[loaded] setPositionIndexTo:pi];
});
loaded++;
}
問題:
ブロックがself.tiles[648]にアクセスしようとするため、例外が発生します。Appleのブロックドキュメントでは、ブロックが作成されたときにブロック内の変数の値がキャプチャされると述べているので、これがどのように可能であるかさえわかりません。実際にロードされた変数の値は648であり、実行せずにループを中止する必要があることを理解しています。他の奇妙な点は、値0もブロックで使用されないことですが、1から始まります。また、ロードされた値に関してブロックがループの前にあることを確認できる場合もあり、値をまったく見逃している場合もあります。 、または2回実行します。ここにいくつかの出力があります:
loaded ->: 612
loaded: 613
loaded ->: 613
loaded ->: 614
loaded: 614
loaded ->: 614
loaded: 615
loaded: 616
loaded ->: 615
loaded: 617
loaded ->: 617
なぜ、そしてどのようにこれが可能ですか?
Appleのドキュメントには、ブロックが作成されたときに、ブロックに対して変更せずに「ロード済み」の値をキャプチャする必要があることが明確に記載されていると思いますが、ご説明いただきありがとうございます。