iOS常用设计模式之单例模式
引言
在很多时间,singleton定义为“有且仅有一个元素的集合”,所以不管那个对象到底有多大,每次我们拿这个对象时都是同一个。在什么情况下会需要单例以及单例在Objective-C中如何实现呢?本节Abel将与您一起探讨一些有关singleton的知识。
目录
- 1、什么是单例模式
- 2、什么时候用单例模式
- 3、Objective-C中单例模式的实现
- 4、线程安全
- 5、总结
1、什么是单例模式
单例模式几乎是设计模式中最简单的了。这一模式的意图是使得类的一个对象成为系统中唯一的实例。要实例这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。我们可以用工厂方法来限制实例化过程。这个方法应该是一个静态的方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
2、什么时候使用单例模式
1、类只能有一个实例,而且必须从一个为人熟知的访问点对其访问。
2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。
3、Objective-C中单例模式的实现
在《设计模式》一书中的原始示例中,单例模式的C++例子如下所求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
知道C++语言的人都能看出来,在上面的C++代码Instance()方法中,检查静态的_instance实例变量,看它是否为0,如果是,会生成一个新的Singleton对象,然后将实例返回,现在我们把它改造成Objective-C版。
那么用Objective-C如何实现单例模式呢?下面我们来新建一个Singleton类,在Singleton.h中实现如下
1 2 3 |
|
在Singleton.m
1 2 3 4 5 6 7 8 9 10 |
|
按照C++改造成Objective-C就完成了。如果真是这样的话,那么单例模式真的是太简单了,但实际上,需要克服一些障碍,才能让单例模式更可靠,可以真正放心地应用于程序中。如果需要实现一个“严格”的单例模式,还需要面对两个主要的障碍。
发起调用的对象不能以其他分配方式实例化对象。否则,就有可能创建多个单例实例。
对单例对象实例化的限制应该与引用计数内存模型共存。
下面我对Singleton.m
的进行改进
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
也许你注意到了,我重载了allocWithZone:
,保持了从sharedInstance
方法返回的单例对象,使用者哪怕使用alloc
时也会返回唯一的实例(alloc
方法中会先调用allocWithZone:
创建对象)。而retain
等内存管理的函数也被重载了,这样实现了合适的内存管理原则。
4、线程安全
如果单例对象要由多个线程访问,那么使它的线程安全至关重要。例子中的Singleton类只能胜任一般用途。要让它线程安全,需要在sharedSingleton静态实例的nil检查周围加入一些@synchronized()程序块或者NSLock实例。如果有其他的属性需要保护,也可以把它们声明为atomic型。
5、总结
到此,单例模式的讲解就到些结束了。不管在哪个平台开发,单例模式都极为常用。如果单例模式还有不懂的地方,可以给我留言。