单例模式

来源:互联网 发布:淘宝海外代购要身份证 编辑:程序博客网 时间:2024/05/18 03:55

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;}
0 0
原创粉丝点击