单例模式

1、单例模式的定义
单例模式确保一个类只有一个实例,并提供一个全局访问点。

2、使用场景
我们希望这个类在整个应用程序中,只有一个对象实例,并且提供一个全局访问接口。单例模式常常被用来管理共享的资源,例如,注册表信息,数据库连接或线程池等。对于全局共享的资源的访问,使用单例可以避免资源访问时数据的不一致问题。

3、单例模式的实现
1)单例模式在Java语言中的实现
对于Java的实现可以简单的概括为单例类没有公开的构造方法,外界不能自行实例化一个对象,只能通过通过这个单例类提供的静态接口方法获得该单例类的实例(单例类的实例化是在该类的内部完成的)。
这里给出两种实现。
其一:紧急加载型(饿汉式)

//在类初始化时,已经实例化对象   
public class Singleton {  
    private Singleton() {}  
    private static final Singleton singleton = new Singleton();  
    public static Singleton getInstance() {  
        return singleton;  
    }  
}  

其二:延迟加载型(懒汉式)

public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {  
        if (uniqueInstance == null) {    
            synchronized (Singleton.class) {    
               if (uniqueInstance == null) {    
                  uniqueInstance = new Singleton();   
               }    
            }    
        }    
        return uniqueInstance;   
    } 
 }

这两种方法都能保证线程安全。饿汉式是在类创建的同时就已经创建好一个静态的对象可供使用,以后不再改变,所以是线程安全的。懒汉式使用了同步锁来保证线程安全,并且使用了双重检查加锁来减少同步的次数。

2)单例模式在Objective-C语言中的实现
先看一下苹果给的方案
Singleton
Singletons provide a globally accessible, shared instance of an object. You can create your own singletons as a way to provide a unified access point to a resource or service that’s shared across an app, such as an audio channel to play sound effects or a network manager to make HTTP requests.
In Objective-C, you can ensure that only one instance of a singleton object is created by wrapping its initialization in a call the dispatch_once function, which executes a block once and only once for the lifetime of an app:

        + (instancetype)sharedInstance {
            static id _sharedInstance = nil;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                _sharedInstance = [[self alloc] init];
            });

            return _sharedInstance;
        }

In Swift, you can simply use a static type property, which is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneously:

        class Singleton {
            static let sharedInstance = Singleton()
        }

If you need to perform additional setup beyond initialization, you can assign the result of the invocation of a closure to the global constant:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()
        // setup code
        return instance
    }()
}

可以看出苹果的实现并不是一种严格的单例模式。如果通过[SomeClass alloc] init][SomeClass sharedInstance] 的方式去获取对象,得到的就是不同的对象。如果你一直使用sharedInstance方法去获取对象的话,那么得到的就是同一个对象。例如系统的NSFileManager类就是这种情况。在实际的开发中,我们可能也使用这种简洁的方式。

对于Objective-C来说,实现一个“严格的单例”可能稍微复杂一些(需要重写的方法较多),不像Java或C++那样提供了很好的机制来实现这一模式。在ARC模式下,我们可以这样来实现:

+ (instancetype)shareInstance {
    return [[self alloc] init];
}

static Singleton *_instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    // 由于alloc方法内部会调用allocWithZone: 所以我们只需要保证在该方法只创建一个对象即可
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken,  ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone {
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}

对于MRC来说,我们还要考虑引用计数内存模型,这个时候我们要重写于内存管理相关的方法。

+ (instancetype)shareInstance {
    return [[self alloc] init];
}

static Singleton *_instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    // 由于alloc方法内部会调用allocWithZone: 所以我们只需要保证在该方法只创建一个对象即可
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

-  (id)copyWithZone:(NSZone *)zone {
    // 因为copy方法必须通过实例对象调用, 所以可以直接返回_instance
    return _instance;
}

-  (id)mutableCopyWithZone:(NSZone *)zone {
    return _instance;
}

-  (oneway void)release {

}

-  (instancetype)retain {
    return _instance;
}

-  (NSUInteger)retainCount {
    return MAXFLOAT;
}

你可能感兴趣的:(设计模式,设计模式)