如何理解NSMutableSet的成员测试和添加竞争条件?

How to understand the member testing and adding race condition of NSMutableSet?

在看《Objective-C 2.0 Phrasebook》这本书的时候,NSMutableSet有一点不太明白,如下,

There is a potential race between testing whether the string is in the set and adding the new one if it isn’t. A thread-safe version of this would require you to acquire a lock after the -member: call, send this message again, and then finally release the lock after adding the new object.

我不明白为什么我应该

send this message again

这是否意味着我应该再次拨打 -member: 电话?请帮我。 任何代码示例将不胜感激。

在Objective-C中,像[mySet member:candidate]这样的表达式将名为member:的“消息”发送给mySet(“接收者”),参数为candidate.它通常被称为“方法调用”或只是“调用”,但 it’s more properly called “sending a message” 或“消息发送”,因为 Objective-C 消息发送中的机制(和定制机会)比在 C++ 或 Java.

等更常见语言的方法调用中

所以是的,当书上说“再次发送这条消息”时,意思是再做一次[mySet member:candidate]。我没看过这本书,但你的引文描述了“双重检查锁定”模式。

但是,如果您从多个线程访问相同的NSMutableSet,那么本书所描述的内容不足以避免竞争条件(如果您不需要只能从单个线程访问 NSMutableSet)。问题是,如果您在线程 A 上说 [mySet addObject:newMember],那么从线程 B 同时访问 mySet 不安全 。在 [= 执行期间19=] 方法,该集合可能处于内部不一致状态,可能(例如)导致另一个线程上的同时 member: 调用崩溃。除了写入访问之外,您还必须将 读取 访问锁定到 mySet,因此双重检查锁定模式不足以保护跨线程共享 NSMutableSet

处理此问题的最佳方法是使用 dispatch_queue_t 来管理对 NSMutableSet 的独占访问,不要担心任何更复杂的事情,除非探查器告诉您这是一个瓶颈。