zoukankan      html  css  js  c++  java
  • 创建单例

    背景

    很多时候,我们在网上,或者开源项目中,看到类似下面这样创建一个单例:

    +(MyClass *)singleton {
        static MyClass *shared = nil;
    
        if(shared == nil) {
            shared = [[MyClass alloc] init];
        }
        return shared;
    }
    

    但是,上面的代码在很多层面是错误的。首先,它不是线程安全的,当多个线程调用这个创建方法时,我们无法确保正确创建了一个实例,有时在苹果的官方例子中也是这么写的。

    如果你必须使用单例,可以使用dispatch_once()

    dispatch_once() 安全地解决了上面存在的问题:

    (1)它保证了在块中的代码将在应用中只调用一次

    (2)它是线程安全的

    (3)它比使用其他方法创建单例更快,比如使用@synchronize()

    @implementation Singleton
    static Singleton *shareSingleton = nil;
    
    +(Singleton*) shareInstance {
        @synchronized(self){  //加锁
            if (shareSingleton == nil) {
                shareSingleton = [[Singleton alloc] init];  
            }
        }
        return shareSingleton;
    }
    

    最佳实践

    所以,创建单例的最佳实践应该是:

    +(MyClass *)singleton {
        static dispatch_once_t pred;
        static MyClass *shared = nil;
    
        dispatch_once(&pred, ^{
            shared = [[MyClass alloc] init];
        });
        return shared;
    }
    

    总结

    在实际项目中,我们应该尽量避免过多使用单例,虽然单例不是什么魔鬼,但是能不用就不用。如果你必须使用单例,也要使用正确的方法来创建它。

  • 相关阅读:
    css3 animate 和关键帧 @-webkit-keyframes
    CSS3 线性渐变(linear-gradient)
    css3 transition平滑过渡
    css3 变形设计涂鸦墙
    css3 图片翻转效果
    溢出隐藏
    顺序表的实现
    数论学习
    从BF算法到kmp算法详解
    王红梅、胡明、王涛编著的《数据结构c++》(第二版)模板类链表超详细代码
  • 原文地址:https://www.cnblogs.com/YungMing/p/4346730.html
Copyright © 2011-2022 走看看