有的时候,在程序开发中,有些代码只想从程序启动就只执行一次,典型的应用场景就是“单例”
// MARK: 一次性执行- (void)once {static dispatch_once_t onceToken;NSLog(@"%ld", onceToken);dispatch_once(&onceToken, ^{[NSThread sleepForTimeInterval:1.0];NSLog(@"一次性吗?");});NSLog(@"come here");}
- dispatch 内部也有一把锁,是能够保证”线程安全”的!而且是苹果公司推荐使用的
- 以下代码用于测试多线程的一次性执行
- (void)demoOnce {for (int i = 0; i < 10; ++i) {dispatch_async(dispatch_get_global_queue(0, 0), ^{[self once];});}}
单例测试
单例的特点
- 在内存中只有一个实例
- 提供一个全局的访问点
单例实现
// 使用 dispatch_once 实现单例+ (instancetype)sharedSingleton {static id instance;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[self alloc] init];});return instance;}// 使用互斥锁实现单例+ (instancetype)sharedSync {static id syncInstance;@synchronized(self) {if (syncInstance == nil) {syncInstance = [[self alloc] init];}}return syncInstance;}
面试时只要实现上面
sharedSingleton方法即可
单例测试
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {long largeNumber = 1000 * 1000;// 测试互斥锁CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();for (long i = 0; i < largeNumber; ++i) {[Singleton sharedSync];}NSLog(@"互斥锁: %f", CFAbsoluteTimeGetCurrent() - start);// 测试 dispatch_oncestart = CFAbsoluteTimeGetCurrent();for (long i = 0; i < largeNumber; ++i) {[Singleton sharedSingleton];}NSLog(@"dispatch_once: %f", CFAbsoluteTimeGetCurrent() - start);}
