由于OC中的方法天生就是public的(就算只写到.m中,在运行时也可以调用到。。。),平时使用的单例方法也未必严谨,所以,看了书,受教了~(还好一般老老实实使用类方法创建单例的无所谓)。
实现一个“严谨”的单例类
一般来说,提供一个类方法入口,使用dispatch_once_t保护,使用静态类变量保存,即可成功一个创建线程安全的单例对象。
但是,当调用者在不知情的情况下,调用传统的二段式创建、new或者allocWithZone方法分配内存,甚至是调用copy或multableCopy方法时,都可以创建新的实例对象。所以,为了避免,就需要我们对这些方法依次堵住,重写时,直接在方法内部调用单例方法即可。并且,单例方法的实例化对象时,使用[[super allocWithZone:nil] init]来替代默认(自身的方法已经被重写了)。即可得到“严谨”的单例类。
关于单例类的继承
平时都不这么用啊。。。确实是。。。不过既然书中提到了,也查阅了一下,说一说哇。。。(当前的示例代码中无法实现此功能)
书中说,使用NSAllocateObject()函数手动分配内存,可以实现子类创建自己的单例对象,但是由于现在是ARC环境,此函数早已不可用,需要对单例类单独“-fno-objc-arc”来开后门才行。另一篇博文IOS单例模式下多线程和继承写法总结里面,也有讨论过,通过查找源码的方式(alloc -> allocWithZone: -> class_createInstance() 的过程),直接使用runtime中的创建实例方法也能达到同样的效果(前提也是MRC环境下),d=====( ̄▽ ̄*)b厉害。
所以,平时不这么用。。。
示例代码地址:Singleton