在 Objective-C 中初始化和使用线程安全静态对象

Initialise and use threadsafe static object in Objective-C

此方法将从多个线程和 returns 一个 static 字典调用,该字典将仅由调用线程读取而不会写入。初始值是动态的,因此内部实现是 NSMutableDictionary.

据我了解,由于对 dictionary 的赋值是 而不是 一个 static 初始化程序,并且它的状态也发生了进一步的变异,因此 @synchronized 块在返回之前是必需的,以确保所有调用线程都能看到初始化值。这是正确的还是我应该删除 @synchronized 并将内存屏障设置为 dispatch_once 块的最后一行?

我只需要确保初始分配的值对所有调用线程可见。

+ (NSDictionary *)threadSafeMethod {
    static NSMutableDictionary *dictionary;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dictionary = [NSMutableDictionary dictionary];
        [dictionary setValue:dynamicValue1 forKey:@"key1"];
        [dictionary setValue:dynamicValue2 forKey:@"key2"];
    });

    @synchronized(dictionary) {
        return dictionary;
    }
}

@synchronized 基本上是锁对象上的互斥。

您使用它的方式只保护对象的 return 而不是它的使用。这样,线程就会互相阻塞来获取字典指针。

更新:由于您的对象在外部是不可变的,因此那里不需要保护。

我怀疑@synchronize 对您的情况有任何用处,请保持原样。初始化将完成一次,其他人将被阻塞,直到第一个完成块。 然后每个人都得到他指向创建的字典的指针,所以所有线程都读取同一个字典并且不再有阻塞。