iOS面试题+基础知识iOS面试

iOS 单例中dispatch_once的原理

2020-04-20  本文已影响0人  Rockerliang

先来段代码:

+ (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。

上一篇 下一篇

猜你喜欢

热点阅读