• 创建单例


    背景

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

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

    总结

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

  • 相关阅读:
    url-pattern / /*匹配
    velocity入门
    配置eclipse插件
    Myeclipse 2014 破解
    Eclipse kepler 安装 Dynamic Web Project差距WTP
    Errors running builder 'Faceted Project Validation Builder' on project
    JSF web.xml的各类参数属性配置
    bpm 学习笔记一
    love is ... ...
    .sh_history文件的管理机制
  • 原文地址:https://www.cnblogs.com/YungMing/p/4346730.html
Copyright © 2020-2023  润新知