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;
    }
    

    总结

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

  • 相关阅读:
    使用binlog日志还原数据详解
    js自定义双击函数
    部署全局ajax处理
    mysql开启binlog日志和慢查询日志
    iOS-静态库,动态库,framework浅析(三)
    iOS-静态库,动态库,framework浅析(二)
    ios-静态库,动态库,framework浅析(一)
    iOS
    xcode工程编译错误:The maximum number of apps for free development profiles has been reached.
    iOS
  • 原文地址:https://www.cnblogs.com/YungMing/p/4346730.html
Copyright © 2011-2022 走看看