我有一个 sessions
属性,一个可变集。我需要迭代集合,但同时我可以用另一种方法更改集合:
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in _sessions) {
/* do something */
}
return nil;
}
- (void) doSomethingElse
{
[_sessions removeObject:…];
}
这不是线程安全的。防弹版本将使用 @synchronized
或调度队列来序列化 _sessions
访问。但是在迭代集合之前简单地复制它有多合理?
- (Session*) sessionWithID: (NSString*) sessionID
{
for (Session *candidate in [_sessions copy]) {
/* do something */
}
return nil;
}
我不太关心性能差异。
最佳答案
But how reasonable is to simply copy the set before iterating over it?
如前所述,不保证线程安全。您需要保证 _sessions
在 -copy
期间不会发生变化。然后迭代不可变的副本是安全的,_sessions
的突变可能会发生在辅助线程或您的实现中。
在许多 Cocoa 集合的情况下,您会发现最好使用不可变的 ivars 和通过将属性声明为 NSSet 类型的
。这样,您可以在写入/设置时进行复制,然后避免在读取时进行复制。这有可能减少副本,具体取决于程序的实际执行方式。一般来说,仅此还不够,您将需要更高级别的同步。copy
来在集合上复制
还请记住,集合中的Session
可能不是线程安全的。即使您的集合访问受到适当保护,您也可能需要保护对这些对象的访问。
关于ios - 在迭代之前复制集合是否足以防止同步问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21857612/