我有一个管理我所有列表的Singleton对象。我们称之为ListStore。
ListStore有一个可变数组,用于存储列表。
@interface ListStore : NSObject
@property (nonatomic, copy) NSMutableArray *lists; // an array of List objects
end
列表有一个可变数组,用于存储事物。
@interface Wanderlist : NSObject <NSCoding, NSCopying>
@property (nonatomic, copy) NSMutableArray *things; // an array of Thing objects
@end
任何时候,后台进程都可以通过ListStore循环并处理所有列表,而用户可能正在与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]
没有被调用。
我知道我可以简单地说{{1}}但我希望至少能更好地了解NSCopying。
答案 0 :(得分:3)
在提交此问题之前,我点击了SO相关问题列表中的问题,找到了我的解决方案。
想到发布我的解决方案并没有什么坏处。
而不是:
NSArray *newLists = [[ListStore sharedStore] lists] copy];
我必须这样做:
NSArray *newLists = [[NSArray alloc] initWithArray:[[ListStore sharedStore] lists] copyItems:true];
- (id)initWithArray:(NSArray *)array copyItems:(BOOL)flag flag: If YES, each object in array receives a copyWithZone: message to create a copy of the object—objects must conform to the NSCopying protocol. In a managed memory environment, this is instead of the retain message the object would otherwise receive. The object copy is then added to the returned array.
一旦我使用了initWithArray:copyItems:,它会自动将copyWithZone发送到我的所有List对象,然后我就可以在list.things
上手动执行copyWithZone。