首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》17.5 线程安全的单例

关灯直达底部

到目前为止,本书开发的都是单线程应用(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对象。