すべてのリストを管理する Singleton オブジェクトがあります。これを ListStore と呼びます。
ListStore には、リストを格納する可変配列があります。
@interface ListStore : NSObject
@property (nonatomic, copy) NSMutableArray *lists; // an array of List objects
end
Lists には、Things を格納する可変配列があります。
@interface Wanderlist : NSObject <NSCoding, NSCopying>
@property (nonatomic, copy) NSMutableArray *things; // an array of Thing objects
@end
バックグラウンド プロセスはいつでも、ListStore を通過し、すべてのリストをループして処理する可能性がありますが、ユーザーはリストを操作している可能性があります。
「列挙中にオブジェクトが変更された」タイプのエラーを防ぐために、次のようにします。
// all of this is in a background thread
NSArray *newLists = [[ListStore sharedStore] lists] copy];
for (List *list in newLists) {
// yay, no more crashes, because I'm enumerating over a copied object, so the user
// can do whatever they want while I'm here
for(Thing *thing in list.things) {
// oh crap, my copy and the original object both reference the same list.things,
// which is why i'm seeing the 'mutation while enumerating" errors still
...
}
}
newLists
コピーしたからこそ、メンバー全員がちゃんとコピーされると最初は思っていました。そうではないことがわかりました。「列挙中にオブジェクトが変更されました」というエラーが引き続き表示されますが、今回は で発生していlist.things
ます。
セットアップで NSCopying を使用して、次のように言うことはできますか?
[[ListStore sharedStore] copy];
copyWithZone:
を呼び出すLists
ので、copyWithZone:
次にthings
?
このように設定しようとしましたcopyWithZone:
が、呼び出されませんでした。
簡単に言うことができることはわかっていますNSArray *newList = [list.things copy]
が、少なくとも NSCopying についてよりよく理解したいと思います。