持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
- 本文主要介绍iOS设计模式中
单例模式
的介绍,单例模式是我们平时使用比较多的一种设计模式,提供了对类的对象所提供的资源的全局的访问点
,因此我们可以使用单例返回的对象
进行传递值等。
1. 什么是单例模式
单例模式
是设计模式的最简单的形式了。这一模式的意图是使得类的一个对象成为系统中的唯一实例。我们通常会使用类方法返回实例对象,因此我们可以使用工厂方法
进行实现改类在程序中只实例化一次
。该方法我们首先判读是否存在实例,不存在的话进行实例之后返回该实例。
在数学中。singleton
指“单元素集合
”,指仅由一个元素组合成的集合。
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2. 什么时候使用单例模式
- 类
只能有一个实例
,而且必须从一个为人熟知
的访问点对其进行访问,比如工厂方法。 - 这个唯一的实例只能
通过子类
化进行拓展,而且拓展的对象不会破坏
客户端代码。单例模式
提供了一个为人熟知
的访问点,提供客户类为共享资源生成唯一实例
,并通过它对共享资源进行访问,虽然静态的全局对象引用或类方法也可以提供全局访问点,但是全局对象无法防止类被实例化一次
以上,而且类方法也缺少消除耦合的灵活性
。
比如我们APP中保存用户的信息类,UserModel
的信息在全局中多次被用到,同时我们只要一次实例化,这个时候使用单例模式就可以提供了灵活性。或者是网络请求
的工具类我们实例化一次,全局都可以使用。
3. 在Cocoa Touch中使用单例模式
我们在开发中会发现大量的单列类,这里简单的介绍下UIApplication
和NSFileManager
。
3.1 UIApplication
每个iOS应用程序都恰好有一个UIApplication
实例(或很少是UIApplication
的子类)。当应用程序启动时,系统调用UIApplicationMain(_:_:_:_:)
函数。除其他任务外,此函数创建一个单例UIApplication
对象,您可以使用shared
访问。
UIApplication
对象为应用程序处理许多内务管理任务
,包括传入的用户事件的最初路由,以及为UIController
分发动作消息给合适的目标。并且还维护应用程序中打开所有UIWindow
对象的列表。应用程序对象总是被分配给一个UIApplicationDelegate
对象,把运行时事件通知给她。
3.2 NSFileManager
文件管理器
对象允许您检查文件系统的内容并对其进行更改。NSFile
类提供了对共享文件管理器对象的便捷访问,该对象适用于大多数类型的文件相关操作。文件管理器对象通常是您与文件系统交互的主要模式
。您使用它来定位、创建、复制和移动文件和目录。您还可以使用它来获取有关文件或目录的信息或更改其某些属性。
可以通过defaultManager
进行访问,但是可能会存在线程安全问题。
可以从多个线程安全
地调用共享NSFile
对象的方法。但是,如果您使用委托接收有关移动、复制、删除和链接操作状态的通知,您应该创建文件管理器对象的唯一实例,将委托分配给该对象,并使用该文件管理器启动操作。
4. 代码展示
单利通常有2种写法,第一种:
static Network *_network;
+(instancetype)share
{
if (!_network) {
_network = [[Network alloc]init];
}
return _network;
}
这样写会在多线程情况下
导致重复创建,不安全。通常会添加一个同步锁
+(instancetype)share
{
@synchronized (self) {
if (!_network) {
_network = [[Network alloc]init];
}
}
return _network;
}
继续优化下,防止每次读取造成卡顿,外面在加一层判断。
+(instancetype)share
{
if (!_network) {
@synchronized (self) {
if (!_network) {
_network = [[Network alloc]init];
}
}
}
return _network;
}
第二种:看下GCD单例写法
static Network *_network;
+(instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_network = [[Network alloc]init];
});
return _network;
}
当然为了防止alloc
和copy
导致实例化我们通常也会实现allocWithzone
和copyWithZone
,用来确定唯一性。
5. 总结
单例模式在我开发生涯中,使用的比较多,但是大量的单例模式使用会造成内存长期处于无法释放的状态
,虽然解决了我们传值
,状态保存
等方便性。但是它违返了单一职责原则
。单例模式可能掩盖不良设计
, 比如程序各组件之间相互了解过多
等。