> 单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。 — 维基百科 ## Objective-C的单例 ```objective-c .h @interface Control: NSObject +(id)getShare; @end .m static Control *mControl; @implementation Control +(id)getShare { if (mControl == nil) { mControl = [[Control alloc] init]; } return mControl; } -(id)init { //你需要初始化的属性。。。 } @end ``` 上面的代码就是一个单例类,通过[Control getShare]获取的Control对象在程序生命周期里任何地方、时间都是mControl这个静态变量。 这种做法会产生一个在.m文件作用域的全局静态变量,而且不能保证mControl被误修改。借助多线程的`dispatch_once`函数进行优化并避免误修改操做: ```objective-c .h @interface Control: NSObject +(id)getShare; @end .m @implementation Control +(id)getShare { static Control *mControl; static dispatch_once_t oncetoken; dispatch_once(&oncetoken,^{ mControl = [[self alloc] init]; }); return mControl; } -(id)init { //你需要初始化的属性。。。 } @end ``` 通过`dispatch_once`保证了`mControl`在应用的生命周期里只会初始化一次,又`mControl`被限制在`getShare`函数的作用域里,避免了外部对`mControl`的可能。 >单例一般用于贯穿整个应用生命周期的管理类,例如:用户信息管理类、应用配置管理类 ## Swift的单例 ```swift class Control { private static let _default = Control() static func default() -> Control { return _default } private init() { //你需要初始化的属性。。。 } } ``` 上面的代码就是Swift的单例类,使用方法是`Control.default()`,Swift中的类可以不继承其它的类,类的私有属性`_default`保存单例对象(保护该对象在外界不会被修改)。并且用`private`修饰init方法,这样就取消了`Control`类在外界初始化的可能。类计算属性的get方法可以代替函数返回_default,所以上面的代码可以优化成下面,这样做`Control.default`就可以获取该类的单例。(也可以像Objective-C那样优化,不过在Swift 3的时候`dispatch_once`方法被移除了,只能通过判断静态对象是否为空来进行初始化了) ```swift class Control { private static let _default = Control() static var `default`: Control { get { return _default } } private init() { //你需要初始化的属性。。。 } } ``` ## 总结 单例就是类方法和静态对象的结合。 ### 不推荐 如果仅仅只要达到单例的效果,可以定义全局对象就可以实现单例的效果,不过这么做会导致内存管理上的不合理。而且在团队开发时不利于同事的使用,也不能保证该对象的安全。
没有评论