根据我之前在 SO 中的讨论(请参阅对可以多次使用的对象的并发性的怀疑,如格式化程序),在这里我提出了一个更理论的问题,关于在应用程序生命周期内创建一次(并且从未修改过的对象,因此是只读的)并且可以从不同的线程访问它们。一个简单的用例是核心数据。格式化程序可用于不同的线程(主线程、导入线程等)。
NSFormatter
例如,创建 s 的成本非常高。基于此,它们可以创建一次然后重复使用。可以遵循的典型模式(也由 NSFormatter 文章中的@mattt 突出显示)如下。
+ (NSNumberFormatter *)numberFormatter {
static NSNumberFormatter *_numberFormatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_numberFormatter = [[NSNumberFormatter alloc] init];
[_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
});
return _numberFormatter;
}
即使我确定这是一种非常好的方法(创建了一种只读/不可变对象),格式化程序也不是线程安全的,因此以线程安全的方式使用它们可能是危险的。当作者注意到可能发生崩溃的不同线程中使用时,我发现了关于 NSDateFormatter 崩溃中的论点的讨论。
NSDateFormatters 不是线程安全的;有一个后台线程试图同时使用相同的格式化程序(因此是随机性的)。
那么,从不同线程访问格式化程序可能会出现什么问题?有什么安全的模式可以遵循吗?