到目前为止,本书开发的都是单线程应用(single-threaded app)。单线程应用无法充分利用多核设备(从iPhone 4S起,世界上大部分iOS设备都属于多核设备)的CPU资源:在同一时间,单线程应用只能使用CPU的一个核,也只能执行一个函数。相反,多线程应用(multi-threaded app)可以同时在不同的CPU核上执行多个函数。
本书第11章是通过以下代码创建单例的:
+ (instancetype)sharedStore
{
static BNRImageStore *sharedStore = nil;
if (!sharedStore) {
sharedStore = [[self alloc] initPrivate];
}
return sharedStore;
}
// 不允许直接调用init方法
- (instancetype)init
{
@throw [NSException exceptionWithName:@“Singleton”
reason:@“Use +[BNRImageStore sharedStore]”
userInfo:nil];
return nil;
}
// 私有初始化方法
- (instancetype)initPrivate
{
self = [super init];
if (self) {
_dictionary = [[NSMutableDictionary alloc] init];
}
return self;
}
以上代码可以在单线程应用中正确创建单例,但是在多线程应用中,以上代码可能会创建多个BNRImageStore对象。同时,某个线程还可能会访问其他线程中没有正确初始化的BNRImageStore对象。
为了确保在多线程应用中只创建一次对象,可以使用dispatch_once()创建线程安全的单例(thread-safe singleton)。
打开BNRImageStore.m,修改sharedStore方法,为BNRImageStore创建线程安全的单例:
+ (instancetype)sharedStore
{
static BNRImageStore *sharedStore = nil;
if (!sharedStore) {
sharedStore = [[self alloc] initPrivate];
}
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedStore = [[self alloc] initPrivate];
});
return sharedStore;
}
构建并运行应用,虽然运行结果不会有任何变化,但是现在sharedStore可以在多核设备中正确返回唯一的BNRImageStore对象。