先来段代码:
+ (instancetype)shareInstance{
static BETestSingleton * single;
static dispatch_once_t onceToken;
NSLog(@"====>%ld",onceToken);
dispatch_once(&onceToken, ^{
NSLog(@"====>block内:%ld",onceToken);
single = [[BETestSingleton alloc] init];
});
NSLog(@"======>block外:%ld",onceToken);
return single;
}
这是利用dispatch_once实现单例的方式,运行看看会输出什么:
====>0
====>block内:768
======>block外:-1
生成完单例对象后,在其他地方调用单例:
NSString *testStr = [BETestSingleton shareInstance].testString;
会输出:
====>-1
======>block外:-1
下面来看一下为什么这么输出以及dispatch_once
的原理:
dispatch_once
主要是根据onceToken
的值来决定怎么去执行代码。
1.当onceToken= 0
时,线程执行dispatch_once
的block中代码
2.当onceToken= -1
时,线程跳过dispatch_once
的block中代码不执行
3.当onceToken
为其他值时,线程被阻塞,等待onceToken值改变
当线程调用shareInstance
,此时onceToken= 0,调用block中的代码,此时onceToken的值变为768。当其他线程再调用shareInstance
方法时,onceToken的值已经是768了,线程阻塞。当block线程执行完block之后,onceToken变为-1.其他线程不再阻塞,跳过block。下次再调用shareInstance
时,block已经为-1.直接跳过block。