菜鸟教程小白 发表于 2022-12-13 06:28:07

ios - 在迭代之前复制集合是否足以防止同步问题?


                                            <p><p>我有一个 <code>sessions</code> 属性,一个可变集合。我需要遍历集合,但同时我可以用另一种方法更改集合:</p>

<pre><code>- (Session*) sessionWithID: (NSString*) sessionID
{
    for (Session *candidate in _sessions) {
      /* do something */
    }
    return nil;
}

- (void) doSomethingElse
{
    ;
}
</code></pre>

<p>这不是线程安全的。防弹版本将使用 <code>@synchronized</code> 或调度队列来序列化 <code>_sessions</code> 访问。但是在迭代之前简单地复制集合有多合理?</p>

<pre><code>- (Session*) sessionWithID: (NSString*) sessionID
{
    for (Session *candidate in ) {
      /* do something */
    }
    return nil;
}
</code></pre>

<p>我不太关心性能差异。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>But how reasonable is to simply copy the set before iterating over it?</p>
</blockquote>

<p>如前所述,它不能保证是线程安全的。您需要保证 <code>_sessions</code> 在 <code>-copy</code> 期间不会发生变异。然后迭代不可变副本是安全的,<code>_sessions</code> 的突变可能发生在辅助线程或您的实现中。</p>

<p>在许多 Cocoa 集合的情况下,您会发现通过将属性声明为 <code>NSSet 类型的 <code>copy</code> 来使用不可变 ivars 和 <em>copy on set</em> 会更可取</code>。这样,您在写入/设置时复制,然后避免在读取时复制。这有可能减少副本,具体取决于您的程序实际执行的方式。通常,仅此一项是不够的,您还需要更高级别的同步。</p>

<p>还要记住,集合中的 <code>Session</code> 可能不是线程安全的。即使您的集合访问受到适当保护,您也可能需要保护对这些对象的访问。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在迭代之前复制集合是否足以防止同步问题?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/21857612/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/21857612/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在迭代之前复制集合是否足以防止同步问题?