• IOS GCD 使用(三)单例模式


    一  Dispatch_once函数简介

         使用dispatch_once提价的代码块,即便你提交多次,只能执行一次。

       

       void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
       第一个参数是一个传出参数用来保存代码块在队列运行时被赋的值,如果你想让自己的代码只执行一次的话,你必须指定一个同样的标识符,其实它是long类型的长整数,即typedef long dispatch_once_t。
        第二个参数是一个代码块,这个代码块没有参数和返回值。

        dispatch_once 中的代码块默认的情况下在当前的线程内中执行(也就是被调用函数所在的线程)

    二 使用

    - (void)viewDidLoad
    {
       [super viewDidLoad]; 
       
        static dispatch_once_t onceToken;
       
     void (^executedOnlyOnce)(void) = ^(void)
        {
           
       static NSUInteger numberOfEntries = 0;
               
     numberOfEntries++;
                NSLog(
    @"Executed %lu time(s)   %@", (unsigned long)numberOfEntries,[NSThread currentThread]);
        };

        dispatch_once(&onceToken, ^(void)
        {
           
     dispatch_async(concurrentQueue,executedOnlyOnce);
        });
       
     dispatch_once(&onceToken, ^(void)
        {
           
     dispatch_async(concurrentQueue,executedOnlyOnce);
        });
        
        
        static dispatch_once_t testToken;
       
     dispatch_once(&testToken, ^(void)
        {
           
     NSLog(@"####:Current thread = %@", [NSThread currentThread]);
        });

        
    }    
     
    输出结果:

    2013-11-11 17:21:21.076 GCDDemo[1410:70b] ####:Current thread = <NSThread: 0x8a1e7c0>{name = (null), num = 1}
    2013-11-11 17:21:21.076 GCDDemo[1410:2a03] Executed 1 time(s)   <NSThread: 0x8a794c0>{name = (null), num = 2}


    观察发现:

    1.使用了同一个dispatch_once_t标识提价的代码块只运行了一次。
    2.使用dispatch_once提交的代码块默认情况下在当前线程内中执行(也就是被调用函数所在的线程),上面例子在主线程中提交的,所以打印的线程号为1.
    3.为了在其他线程中运行dipsatch_once提交的代码块,可以将代码块的任务提交到GCD队列中。

    三 单例模式

           可以利用dispatch_once的性质来实现单例模式,将我们自定义类的对象创建过程封装到一个代码块中,然后以dispath_once的方式来提交。

    看代码:

        +(MyClass*)  sharedInstance
        {
           
     static  MyClass *_sharedMyClass;
           
     static dispatch_once_t token;
           
           
     dispatch_once(&token,^{ _sharedMyClass = [[MyClass alloc] initWith:something];} );
           
           
     return _sharedMyClass;
        }


    注意:  1.使用dispatch_once是线程安全的。
                 2.使用上面例子来实现的单例是“伪单例”,也就是说只有当使用者用MyClass *obj = [MyClass shardInstance];方式来取得对象时候才算是单例,但是我们无法阻止其直接只用alloc来创建自己的对象。


  • 相关阅读:
    CODEVS 3137 栈练习1
    CODEVS 3138 栈练习2
    线段树———模板
    深度优先搜索与广度优先搜索———模板
    犯罪团伙 codevs 3554
    嘟!数字三角形 W WW WWW集合!
    寻找子串位置 codevs 1204
    流输入练习——寻找Sb.VI codevs 3096
    C++之路进阶——codevs3287(货车运输)
    c++之路进阶——codevs4543(普通平衡树)
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3478564.html
Copyright © 2020-2023  润新知