创建单例
背景
很多时候,我们在网上,或者开源项目中,看到类似下面这样创建一个单例:
+(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;
}
总结
在实际项目中,我们应该尽量避免过多使用单例,虽然单例不是什么魔鬼,但是能不用就不用。如果你必须使用单例,也要使用正确的方法来创建它。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号