模拟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 }

 


 

posted @ 2016-05-30 09:20  FMDN  阅读(248)  评论(0编辑  收藏  举报