你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> 模擬dispatch_once

模擬dispatch_once

編輯:IOS技巧綜合
[摘要]本文是對模擬dispatch_once的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

dispatch_once

dispatch_once可以保證一段代碼只被執行一次,因此出現之後使用最多的場景就是實現單例。本文來模擬實現dispatch_once的功能。

模擬dispatch_once

直接上代碼

static NSMutableDictionary *lockMapping = nil;

void do_once(int *predicate, void(^block)()){
    if(*predicate != -1){
        NSLock *lock = nil;
        
        @synchronized ([NSObject class]) {
            NSLog(@"get lock");
            if(lockMapping == nil){
                lockMapping = [NSMutableDictionary dictionary];
            }
            
            NSString *key = [NSString stringWithFormat:@"%p", predicate];
            if(![lockMapping objectForKey:key]){
                [lockMapping setObject:[[NSLock alloc] init]
                                forKey:key];
            }
            
            lock = [lockMapping objectForKey:key];
        }
        
        [lock lock];
        
        if(*predicate != -1){
            block();
            *predicate = -1;
        }
        
        [lock unlock];
    }
}

原理很簡單,就不做過多解釋了。使用:

@interface Test : NSObject
+ (instancetype)shareInstance;
@end

@implementation Test
+ (instancetype)shareInstance{
    static int token;
    static Test *t = nil;
    do_once(&token, ^{
        t = [[Test alloc] init];
        
        NSLog(@"execute once");
    });
    
    NSLog(@"execute every time");
    return t;
}
@end

測試:

int main()
{
    for(int i = 0; i < 100; i++){
        dispatch_async(dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT), ^{
            [Test shareInstance];
        });
    }
    
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
    
    return 0;
}
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved