模拟dispatch_once
Posted 小敏的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟dispatch_once相关的知识,希望对你有一定的参考价值。
dispatch_once
dispatch_once可以保证一段代码只被执行一次,因此出现之后使用最多的场景就是实现单例。本文来模拟实现dispatch_once的功能。
模拟dispatch_once
直接上代码
1 static NSMutableDictionary 2 *lockMapping = nil; 3 void do_once(int *predicate, void(^block)()){ 4 if(*predicate != -1){ 5 NSLock *lock = nil; 6 @synchronized ([NSObject class]) { 7 NSLog(@"get lock"); 8 if(lockMapping == nil){ 9 lockMapping = [NSMutableDictionary dictionary]; 10 } 11 NSString *key = [NSString stringWithFormat:@"%p", predicate]; 12 if(![lockMapping objectForKey:key]){ 13 [lockMapping setObject:[[NSLock alloc] init] forKey:key]; 14 } 15 16 lock = [lockMapping objectForKey:key]; 17 } 18 19 [lock lock]; 20 if(*predicate != -1){ 21 block(); 22 *predicate = -1; 23 } 24 25 [lock unlock]; 26 } 27 } 28 29 30 原理很简单,就不做过多解释了。使用: 31 32 33 34 @interface Test : NSObject 35 (instancetype)shareInstance; 36 @end 37 38 @implementation Test 39 40 (instancetype)shareInstance{ 41 static int token; 42 static Test *t = nil; 43 do_once(&token, ^{ 44 t = [[Test alloc] init]; 45 NSLog(@"execute once"); 46 }); 47 NSLog(@"execute every time"); 48 return t; 49 }@end
测试:
1 int main() 2 { for(int i = 0; i < 100; i++){ 3 dispatch_async(dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT), ^{ 4 [Test shareInstance]; 5 }); 6 } 7 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]]; 8 return 0; 9 }
以上是关于模拟dispatch_once的主要内容,如果未能解决你的问题,请参考以下文章