iOS单例实现方法
1 Objective-C的实现方式
@interface Tool: NSObject +(instancetype)sharedInstance;
@end @implementation Tool +(instancetype)sharedInstance { static Tool *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[[self class] alloc] init]; }) return instance; } @end
关于单例,以下三点必须注意:
(1) 单例必须是唯一的,所以它才被称为单例。在一个应用程序的生命周期里,有且只有一个实例存在。单例的存在给我们提供了一个唯一的全局状态。比如NSNotificaton,Application,NSuserDefault都是单例.
(2) 为了保持一个单例的唯一性,单例的构造器必须是私有的。这防止其他对象也能创建出单例类的实例。
(3) 为了确保单例在应用程序的整个生命周期是唯一的,它就必须是线程安全的。简单来说,如果你写单例的方式是错误的,就有可能会有两个线程尝试在同一时间初始化同一个单例,这样就有潜在的风险得到两个不同额单例。这就意味着我们需要用到GCD的dispatch_once来确保初始化单例的代码在运行时只执行一次。
2 Swift的实现方式
class Tool: NSObject { static let sharedInstance = Tool() //私有化构造方法,防止其他对象使用这个类的默认方法‘()’来进行初始化 private override init() { } }
这会你可能会问我为什么没有在我们的结构体和全局变量实现中看不到dispatch_once。但其实Apple指出,这两个方法同时满足了我上面提到的dispatch_once条文。下面就截取他们写的Swift Blog中的一段话来证明他们以将dispatch_once整合进去了:
“全局变量(静态成员变量和结构体以及枚举)的延迟构造器在其被第一次访问时会加载,并以dispatch_once
的方式启动来确保初始化的原子性。这让你写代码时可以用一种很酷的方式来使用dispatch_once
:直接用一个全局变量的构造器去做初始化并用private来修饰。“ — Apple’s Swift Blog
以上内容摘自链接:http://www.devtf.cn/?p=937