GCD8: 在GCD上让一个任务最多执行一次
问题:
在 APP 的生命周期内你想确保每段代码只执行一次,即使它在代码的不同地方多次调用(比如单例的初始化)。
方案:
使用 dispatch_once 函数
例子:
static dispatch_once_t onceToken; void (^executedOnlyOnce)(void) = ^{ static NSUInteger numberOfEntries = 0; numberOfEntries++; NSLog(@"Executed %lu time(s)", (unsigned long)numberOfEntries); }; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //dispatch_once函数学习 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //dispatch_once(<#dispatch_once_t *predicate#>, <#^(void)block#>) dispatch_once(&onceToken, ^{ dispatch_async(concurrentQueue, executedOnlyOnce); }); dispatch_once(&onceToken, ^{ dispatch_async(concurrentQueue, executedOnlyOnce); }); return YES; }
虽然我们使用 dispatch_once 两次尝试调 executedOnlyOnce Block Object,事实上 GCD 对于这个 Block Object 只执行了一次,因为两次传递到 dispatch_once 函数的标识符都一样。
Apple 在其 Cocoa Fundamentals Guide 向程序员展示了如何创建一个单例。这个源代码非常老,还没有更新到使用 GCD 或者 ARC(自动引用计数)。为了初始化一个对象的共享实例,我们可以改变这种模式来使用 GCD 和 dispatch_once 函数,就像这样:
#import "MySingleton.h" @implementation MySingleton -(id)sharedInstance{ static MySingleton *SharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ SharedInstance = [MySingleton new]; }); return SharedInstance; } @end