我有一个管理我所有列表的 Singleton 对象。我们称它为 ListStore。
ListStore 有一个可变数组,用于存储列表。
@interface ListStore : NSObject
@property (nonatomic, copy) NSMutableArray *lists; // an array of List objects
end
Lists 有一个可变数组,用于存储事物。
@interface Wanderlist : NSObject <NSCoding, NSCopying>
@property (nonatomic, copy) NSMutableArray *things; // an array of Thing objects
@end
在任何时候,后台进程都可能通过 ListStore 并循环处理所有 List,而用户可能正在与 List 交互。
为了防止“对象在被枚举时发生变异”类型错误,我这样做:
// 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。