单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
下面来看看中Objective-C和C#的单例都是怎样写的:
Singleton.h文件
@interface Singleton : NSObject + (Singleton *) sharedInstance; @end
Singleton.m文件
1 @implementation Singleton 2 3 static Singleton * sharedSingleton = nil; 4 5 + (Singleton *) sharedInstance 6 { 7 if (sharedSingleton == nil) { 8 sharedSingleton = [[super allocWithZone:NULL] init]; 9 } 10 return sharedSingleton; 11 } 12 13 + (id) allocWithZone:(struct _NSZone *)zone 14 { 15 return [[self sharedInstance] retain]; 16 } 17 18 - (id) copyWithZone:(NSZone *) zone 19 { 20 return self; 21 } 22 23 - (id) retain 24 { 25 return self; 26 } 27 28 - (NSUInteger) retainCount 29 { 30 return NSUIntegerMax; 31 } 32 33 34 - (void) release 35 { 36 // 37 } 38 39 - (id) autorelease 40 { 41 return self; 42 } 43 44 @end
•首先必须创建一个全局实例,通常存放在一个全局变量中,此全局变量设置为nil
•提供工厂方法对该全局实例进行访问,检查该变量是否为nil,如果nil就创建一个新的实例,最后返回全局实例
•全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,所以需要重写该方法,防止通过标准的alloc方式创建新的实例
•为了防止通过copy方法得到新的实例,需要实现-copyWithZone方法
•只需在此方法中返回本身对象即可,引用计数也不需要进行改变,因为单例模式下的对象是不允许销毁的,所以也就不用保留
•因为全局实例不允许释放,所以retain,release,autorelease方法均需重写
1 /// <summary> 2 /// 单例设计模式 3 /// </summary> 4 public class Singleton 5 { 6 /// <summary> 7 /// volatile多用于多线程的环境,当一个变量定义为volatile时,读取这个变量的值时候每次都是从momery里面读取而不是从cache读。这样做是为了保证读取该变量的信息都是最新的,而无论其他线程如何更新这个变量。 8 /// </summary> 9 private volatile static Singleton _instance = null; 10 //线程锁定辅助对象 11 private static readonly object Lock = new object(); 12 13 /// <summary> 14 /// 私有的默认构造函数 15 /// </summary> 16 private Singleton() 17 { 18 19 } 20 21 public static Singleton Instance() 22 { 23 //这种实现方式对多线程来说是安全的,同时线程不是每次都加锁 24 if (_instance == null) 25 { 26 lock (Lock) 27 { 28 if (_instance == null) 29 { 30 _instance = new Singleton(); 31 } 32 } 33 } 34 return _instance; 35 } 36 }