iOS 21种设计模式之单例(Singleton)

来源:互联网 发布:端口号占用查询 编辑:程序博客网 时间:2024/06/06 17:08

感谢

感谢《Pro Objective-C Design Pattern for iOS》一书,这个博客系列由很多灵感源自次书。同时,也感谢Wiki以及一些博客博主。每篇文章最后,都会列出参考链接。


这个系列的文章

  • 工厂
  • 抽象工厂
  • 单例
  • 原型
  • 生成器
  • 适配器
  • 桥接
  • 中介者
  • 观察者
  • 组合
  • 迭代器
  • 访问者
  • 装饰
  • 责任链
  • 模版
  • 策略
  • 命令
  • 享元
  • 代理
  • 备忘录
  • 总结篇:MVC
  • 进阶篇:MVVM

设计模式是为了解决一类问题而出现的,要深刻理解某个模式的应用场景,优点,缺点。千万不要为了使用而实用,那样很可能写出不伦不类的东西。

对于同一种模式,每个人的理解都不同,能解决实际问题才是关键,所以,一定要搞清楚每种设计模式究竟解决了那一类问题,对于设计模式,可以首先理解设计出的接口,再理接口内部的实现


什么是单例模式?

保证类只有一个实例,并且提供一个访问它的全局访问点

//客户端代码let instance  = Singletonlass.sharedInstance()
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在C++中,可以让构造函数为private,隐藏对应接口,但是在iOS开发中不需要,也很难做到。

在Cocoa中,单例模式的使用是十分广泛的,例如UIApplication,NSFileManager.包括一些知名的开源库,AFNetworking,SDWebImage,MagicRecord在架构的时候,也使用了单例。单例使得在使用类的时候不需要强引用一个对象。


解决什么问题?

  • 类只能有一个实例,例如一个App只能有一个UIApplication实例
  • 唯一的实例只能通过继承来扩展,并且扩展后客户端的代码不需要任何修改

什么时候使用单例?

- 类只能有一个实例,例如一个App只能有一个UIApplication实例 
- 通常单例的生命周期和App的生命周期相同,单例作为全局的访问点


不要滥用单例模式

关于单例模式的使用,objc.io的这篇文章讲的很好,摘取一些观点

  • 单例是一种全局状态,意味着App的任何地方都可以和这个单例进行交互,无形中增加了代码的耦合行
  • 单例的生命周期难以控制,虽然可以在单例中提供方法设为nil进行释放。

举个例子吧,

在我的App中,要设计一个类来统计用户的行为(这里不用友盟等第三方统计平台是因为不方便),这个类的主要任务有以下几点:

  1. 在Sandbox中建立一个Log目录,把用户行为Log到本地;
  2. 维护内存中的Log缓冲区(虽然Log相关的操作都在后台,但是还是不想频繁的于物理存储交互);
  3. 同服务器进行同步,同时根据同步的结果清理文件;
  4. 在必要的时候,能根据后台返回数据禁止Log;

那么,如何设计这个类呢?

这个类的特点:App中许多控件 or Controller都需要同它进行交互;这个类不管现在还是以后,都可以和App生命周期一致。

所以,这个类使用了单例。同时,提供类函数这样的接口(暂时没讲到接口相关的设计模式)。


Objective C中的单例

+ (instancetype)sharedSingleton {    static Singleton *_sharedSingleton = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _sharedSingleton = [[Singleton alloc] init];    });    return _sharedSingleton;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Swift的单例

注意,在Swift中由let声明的类常量支持惰性初始化(lazy),并且是线程安全的

class SingletonA {    static let sharedInstance = SingletonA()    //Other}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

当然,也可以像Objective C中那么写

class Singleton {    class var sharedInstance: Singleton {        struct Static {            static var onceToken: dispatch_once_t = 0            static var instance: Singleton? = nil        }        dispatch_once(&Static.onceToken) {            Static.instance = Singleton()        }        return Static.instance!    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

参考链接

  • WIKI Singleton Pattern
  • objc.io避免滥用单例
  • StackOverflow-When to use Singleton in iOS
0 0
原创粉丝点击