概念:单例模式就是整个程序中,该类只能有一个实例。(也就是说该类只能创建一个对象,以后用到的该类的对象都是同一个对象来的)
作用:用于进行资源的共享,也可防止内存的浪费。
注意:确保使用者只能通过getInstance方法才能获得,单例类的唯一实例。
Objective-C中,重写allocWithZone方法,保证即使用户用 alloc方法直接创建单例类的实例,
要重写copyWithZone方法,保证用户使用copy方法创建单例类的实例。
返回的也只是此单例类的唯一静态变量。
需要考虑线程安全,可使用dispatch_once(如果被多个线程调用,该函数会同步等等直至代码块完成)或者@synchronized。
例子:
1、iOS中有很多用到单例的例子,例如以下都是使用单例模式实现的
- [UIApplication sharedApplication]
- [NSNotificationCenter defaultCenter]
- [NSBundle mainBunle]
- [NSFileManage defaultManager]
2、大部分情况下是我们自己编写单例的类
以下先介绍如何使用@synchronized来进行单例类的编写(这是一种比较古老的写法,以前的代码都是这么写的,但是现在已经修改了,现在的代码中基本上都不这么写)
//1.定义静态变量,设置为nil
static Singleton *sharedObj = nil;
//2.编写shareInstance方法来进行实例化,使用@synchronized来实现线程安全,判断shareObj为空的情况下才进行实例化。
+ (Singleton *) sharedInstance //注意,该类方法也要声明到interface中去
{
@synchronized (self)
{
if (sharedObj == nil)
{
[[self alloc] init];
}
}
return sharedObj;
}
//3.重写allocWithZone方法,防止别人使用alloc新建的是一个新的实例
+ (id) allocWithZone:(NSZone *)zone
{
@synchronized (self) {
if (sharedObj == nil) {
sharedObj = [super allocWithZone:zone];
return sharedObj;
}
}
return nil;
}
//4.重写init方法,防止别人使用init新建的是一个新的实例
- (id)init
{
@synchronized(self) {
[super init];//往往放一些要初始化的变量.
return self;
}
}
//5.重写其他的一些方法
//确保被copy的对象也是唯一的
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
//确保计数器唯一
- (id)retain
{
return self;
}
//确保计数唯一
- (id)autorelease
{
return self;
}
//让变量不会因为引入该方法而被释放
-(oneway void)release
{
}
现在主流的单例写法,实际上我们用gcd的dispatch_once替换@synchronized方式,既能提高效率,又能自动适配多核cpu问题,因此我们再来看看dispatch_once创建单例的例子
static Singleton *sharedObj = nil;
+ (<span class="s1" style="font-family: Arial, Helvetica, sans-serif;">instancetype</span><span style="font-family: Arial, Helvetica, sans-serif;">)sharedInstance{ //注意该类也要声明到interface中去</span>
static dispatch_once_t once;
dispatch_once(&once,^{
sharedObj = [[self alloc] init];
//这里也可以给该例的变量赋值,初始化等。
});
return sharedSingleton;
}