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

时间:2015-04-14 05:32:31

标签: ios objective-c thread-safety grand-central-dispatch

此方法将从多个线程调用并返回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;
    }
}

1 个答案:

答案 0 :(得分:0)

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

您使用它的方式仅保护对象的返回而不是它的使用。因此,线程将相互阻塞以获取字典指针。

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

我怀疑@synchronize在你的情况下完全没用,只是保持原样。初始化将完成一次,其他将被阻止,直到第一行完成块。 然后每个人都会得到他创建的字典的指针,所以所有线程都读取相同的字典,并且不再有阻塞。