zoukankan      html  css  js  c++  java
  • IOS 单例分析

    GCD还提供单次初始化支持,这个与pthread中的函数 pthread_once 很相似。GCD提供的方式的优点在于它使用block而非函数指针,这就允许更自然的代码方式。
      这个特性的主要用途是惰性单例初始化或者其他的线程安全数据共享。典型的单例初始化技术看起来像这样(线程安全的):

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    + (id)sharedWhatever
    {
        staticWhatever *whatever = nil;
        @synchronized([Whateverclass])
        {
            if(!whatever)
                whatever = [[Whatever alloc] init];
        }
        returnwhatever;
    }

      这挺好的,但是代价比较昂贵;每次调用 +sharedWhatever 函数都会付出取锁的代价,即使这个锁只需要进行一次。确实有更风骚的方式来实现这个,使用类似双向锁或者是原子操作的东西,但是这样挺难弄而且容易出错。创建单例有更加简单的方式,使用GCD,我们可以这样重写上面的方法,使用函数 dispatch_once:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    + (id)sharedWhatever
    {
        staticdispatch_once_t pred;
        staticWhatever *whatever = nil;
        dispatch_once(&pred, ^{
            whatever = [[Whatever alloc] init];
        });
        returnwhatever;
    }

      该方法有很多优势:
      1  线程安全
      2  很好满足静态分析器要求
      3  和自动引用计数(ARC)兼容
      4  仅需要少量代码
      这个稍微比 @synchronized方法简单些,并且GCD确保以更快的方式完成这些检测,它保证block中的代码在任何线程通过 dispatch_once 调用之前被执行,但它不会强制每次调用这个函数都让代码进行同步控制。实际上,如果你去看这个函数所在的头文件,你会发现目前它的实现其实是一个宏,进行了内联的初始化测试,这意味着通常情况下,你不用付出函数调用的负载代价,并且会有更少的同步控制负载。

  • 相关阅读:
    mvc 注册脚本的其他方法
    如何将html代码转换为Xml并生成Dom树
    用TFIDF值来判断词的重要性
    oem key
    vs2010 下的ado.net 实体模型创建数据库时datetime 类型的问题
    asp.net mvc 动态注册脚本
    ASP.NET 中如何对生成的 HTML 内容流进行控制
    C# 子窗体调用父窗体的方法
    layui 弹出新页面
    winform excel导入进度条
  • 原文地址:https://www.cnblogs.com/gaohe/p/4481274.html
Copyright © 2011-2022 走看看