我有一个 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 集合的情况下,您会发现通过将属性声明为 NSSet 类型的
。这样,您在写入/设置时复制,然后避免在读取时复制。这有可能减少副本,具体取决于您的程序实际执行的方式。通常,仅此一项是不够的,您还需要更高级别的同步。copy
来使用不可变 ivars 和 copy on set 会更可取
还要记住,集合中的 Session
可能不是线程安全的。即使您的集合访问受到适当保护,您也可能需要保护对这些对象的访问。
关于ios - 在迭代之前复制集合是否足以防止同步问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21857612/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |