iOS 单例模式简介
简介:
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问。
单例模式三要素:
1.该类有且只有一个实例;
2.该类必须能够自行创建这个实例;
3.该类必须能够自行向整个系统提====供这个实例。
作用:
1.如果说创建一个对象会耗费很多系统资源,那么此时采用单例模式,因为只需要一个实例,会节省alloc的时间
2.在IOS开发中,如果很多模块都要使用同一个变量,此时如果把该变量放入单例类,则所有访问该变量的调用变得很容易,否则,只能通过一个模块传递给另外一个模块,这样增加了风险和复杂度
优点:
1、提供了对唯一实例的受控访问。
2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
3、允许可变数目的实例。
缺点:
1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。
2、单例类的职责过重,在一定程度上违背了“单一职责原则”。
3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
应用场景:
整个程序共用一份资源时(我们只需要对这份资源初始化一次)可以使用单例
例如:
1.设置单例类访问应用的配置信息、
2.用户的个人信息登陆后用nsuserdefaults 存储,对登录类进一步采用单例封装方便全局访问
3.封装一个单例对应用多处对同一本地数据库进行操作
代码示例
在objective-c中要实现一个单例类,至少需要做以下四个步骤:
1、为单例对象实现一个静态实例,并初始化,然后设置成nil,
2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,
3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,
4、适当实现copyWithZone(mrc还需要实现以下内存管理方法)
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (id)autorelease { return self; }
以下为实现单例的两种常用方式:
```
单例模式- ARC -方法一
ARC中单例模式的实现
在 .m中保留一个全局的static的实例
staticid_instance;
//重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (instancetype)allocWithZone:(struct_NSZone*)zone
{
@synchronized(self)
{
if(_instance ==nil)
{
_instance = [super allocWithZone:zone];
}
}
return_instance;
}
提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedInstanceTool
{
@synchronized(self)
{
if (_instance ==nil)
{
_instance = [[self alloc] init];
}
}
return_instance;
}
实现copyWithZone:方法
-(id)copyWithZone:(struct_NSZone*)zone{return_instance; }
我们在sharedInstanceTool,首先检查类的唯一实例是否已经创建,如果就会创建实例并将其返回。而之所以调用super而不是self,是因为已经在self中重载了基本的对象分配的方法,需要借用父类的功能来帮助处理底层内存的分配。
在allocWithZone:(struct _NSZone*)zone方法中,只是返回从sharedInstanceTool方法返回的类实例。而同样的在Cocoa框架中调用allocWithZone:(struct _NSZone*)zone会分配内存,引用计数会设置为1,然后返回实例。同样的重写(id)copyWithZone:(struct _NSZone *)zone方法,也是为了保证不会返回实例的副本,而是返回self.返回同一个实例。
```
方法二
```
#import"Singleton.h"
@implementationSingleton
staticSingleton* _instance = nil;
+(instancetype)shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL]init] ;
}) ;
return_instance ;
}
+(id)allocWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
}
-(id)copyWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
}
@end
```