OGeek|极客世界-中国程序员成长平台

标题: ios - 在迭代之前复制集合是否足以防止同步问题? [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 06:28
标题: ios - 在迭代之前复制集合是否足以防止同步问题?

我有一个 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;
}

我不太关心性能差异。



Best Answer-推荐答案


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/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4