GCD を介して にアクセスする 2 つの異なるスレッドがNSMutableArray
あり、一方のスレッドが変更可能な配列に基づいて新しい配列を作成し、もう一方のスレッドが配列からレコードを削除している場合、これは問題になると予想できますか? つまり、単に配列を「読み取っている」と思われるコピーは、その時点で配列にあるものを取得するべきではありませんか? どちらのスレッドでも配列を列挙していませんが、まだクラッシュしています。読み取りルーチンを削除するとすぐに、正常に動作します。
これが「読み取り」です:
dispatch_async(saveQueue, ^{
NSDictionary*tempstocks=[NSDictionary dictionaryWithDictionary:self.data];
このスレッドで次のようにクラッシュします。*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[9]'
別のスレッドで何が起こっているかを次に示します。
[self.data removeObjectForKey:item];
列挙中に変更できないことはわかっていますが、変更中に読んでも大丈夫だと思います。取得した変更されたオブジェクトのバージョンがわからない場合がありますが、これは問題ではないと思いますが、明らかにそうです. おそらく、dictionaryWithDictionary
メソッドは最初に X オブジェクトを参照する操作を実行していますが、ルーチンが完了するまでに XY オブジェクトが含まれているため、self.data
実行時に 1 回のスナップでディクショナリ全体を「キャプチャ」するのではなく、本質的にどれが列挙されるかdictionaryWithDictionary
を列挙しています。self.data
列挙中の突然変異と同じ問題?