gpt4 book ai didi

objective-c - 从不同线程访问只读对象的思考

转载 作者:太空狗 更新时间:2023-10-30 03:58:48 26 4
gpt4 key购买 nike

基于我之前在 SO 中的讨论(参见 Doubts on concurrency with objects that can be used multiple times like formatters),在这里我要问一个关于对象的更理论性的问题,这些对象在应用程序生命周期中只创建一次(并且从未修改过,因此是只读的)并且它们可以从不同的线程访问。一个简单的用例是核心数据。格式化程序可以在不同的线程(主线程、导入线程等)中使用。

例如,

NSFormatter 的创建成本非常高。基于此,他们可以创建一次然后重复使用。可以遵循的典型模式(@mattt 在 NSFormatter 文章中也突出显示)如下。

+ (NSNumberFormatter *)numberFormatter {
static NSNumberFormatter *_numberFormatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_numberFormatter = [[NSNumberFormatter alloc] init];
[_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
});

return _numberFormatter;
}

即使我确定这是一个非常好的方法(创建了一种只读/不可变对象(immutable对象)),格式化程序不是线程安全的,因此以线程安全的方式使用它们可能是危险的。我在 NSDateFormatter crashes when used from different threads 中找到了关于该论点的讨论。作者注意到可能发生崩溃的地方。

NSDateFormatters are not thread safe; there was a background thread attempting to use the same formatter at the same time (hence the randomness).

那么,从不同线程访问格式化程序可能会出现什么问题?有什么安全模式可以遵循吗?

最佳答案

格式化程序的具体答案:

在 iOS 7/OSX 10.9 之前,即使是对格式化程序的只读访问也不是线程安全的。 ICU 有大量惰性计算来响应请求,如果同时完成这些计算可能会崩溃或产生不正确的结果。

在 iOS 7/OSX 10.9 中,NSDateFormatterNSNumberFormatter 在内部使用锁来序列化对底层 ICU 代码的访问,从而防止了这个问题。

一般答案:

Real-only access/immutable objects 确实通常是线程安全的,但很难甚至不可能分辨出哪些东西实际上是内部不可变的,哪些只是向外界呈现一个不可变的接口(interface)。

在你自己的代码中,你可以知道这一点。使用其他人的类(class)时,您必须依赖他们关于如何安全使用他们的类(class)的文档。

(编辑,因为请求了对格式化程序进行序列化访问的示例)

// in the dispatch_once where you create the formatter
dispatch_queue_t formatterQueue = dispatch_queue_create("date formatter queue", 0);

// where you use the formatter
dispatch_sync(formatterQueue, ^{ (do whatever you wanted to do with the formatter) });

关于objective-c - 从不同线程访问只读对象的思考,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19960287/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com