1.单例模式概述
单例模式是一个类在系统中只有一个实例对象,所有地方都共享一份资源。而且该实例易于供外界访问。
这在iOS开发中,是一种很有用的设计方式,iOS系统本身也有很多这种单例类,比如:
UIApplication
NSNotificationCenter
NSFileManager
NSUserDefaults
NSURLCache
NSHTTPCookieStorage
2.为什么使用单例模式
总结来说就是全局共享数据,节约资源,提高性能。分散来说:
情况一:如果一个类创建的时候非常的耗费资源或影响性能,可以考虑单例;
情况二:如果一个类系统中只能创建一个实例,且它的所有数据可以共享。可以考虑单例。
3.单例的优缺点
优点:节省资源,提供性能,易于访问。
缺点:耗时较多(因为每次获取前需要判断是否已存在了实例,特别在多线程,在线程安全情况下还有可能造成资源等待)
单例模式不一定都是线程安全的,不同线程在线程不安全的情况下都要访问一个单例对象会引起并发问题,所以在设计的时候需要考虑多线程的安全问题。
4.单例的实现(步步优化)
直接代码:
MySingletonClass.h
MySingletonClass.m
上面的的实现方法,初步看没什么问题。但是如果外部调用的时候,不走寻常路,用alloc来创建,还能保证系统中只有一MySingletonClass吗?看下图:
如果上图所示,如果使用的时候,都是通过类方法.方法来用的话,是没问题,始终只有一个实例。
但是如果通过new/alloc来创建实例,那就不能保证系统中只有一个实例(实例的地址在变化,调用的结果也不是递增的,说明不是一个实例)MySingletonClass。所以要真正实现系统中只有一个实例,那看来需要重写alloc了。
修改后的代码如下:
结果如下图所示
这样修改后,解决了上面所说的问题,现在不管事new还是alloc都只有一个实例对象,地址都是0x60800001ae90,调用次数也是递增的。
但是除了new/alloc可以创建对象,也可以使用copy/mulcopy,那还是只有一个实例吗?
结果崩溃的,这万万不行的。这点异常都处理不好,需要继续优化。修改如下:
结果:
如上图所示,各种访问方式,还是只有一个实例(对象地址没变,调用次数递增),也没有崩溃。
这才是一个优雅成功的单例呀。
若还有其他补充,欢迎大家一起讨论,嘻嘻
网友评论
不用这么多方法
改成你那样,虽然用alloc/new创建不走这个单列方法,但是还是创建了新对象
你试一下?
[[super allocWithZone:NULL] init]
就不需要重写 allocWithZone方法了