iOS单例
1.单例模式是一种设计模式,为我们的程序提供一个公共的接口,即引入这个单例类的文件,我们不管在程序中的哪个地方声明一个该类对象,其实都是同一个对象,啥都一样。
2.单例模式的一般写法
@interface SingleClass : NSObject
+(SingleClass *) shareInstance ;
@end
@implementation SingleClass
static SingleClass* instance = nil;
+(SingleClass*) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init] ;
}) ;
return instance ;
}
@end
SingleClass *class1 = [SingleClass shareInstance];
SingleClass *class2 = [SingleClass shareInstance];
以上两个对象其实是单例的目的,但是我们在取单例声明该单例对象的时候,必须以上边这个静态方法
但是下边这种声明对象的方法,其实在堆中alloc一个空间,与上边就不是一个对象了,单例的目的就失效了,所以要这样写单例,必须保证每次声明对象都用“shareInstance”方法
SingleClass *class3 = [[SingleClass alloc] init];
那么问题就来了,我们通过不同的途径得到不同的对象,显然是不行的。我们必须要确保对象的唯一性,所以我们就需要封锁用户通过alloc和init以及copy来构造对象这条道路。我们知道,创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,我们要确保对象的唯一性,因此在第一步这个阶段我们就要拦截它。当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法中调用shareInstance方法返回单例对象,这样就可以达到我们的目的。拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用shareInstance方法返回单例对象。看代码吧:
static SingleClass* instance = nil;
@implementation SingleClass
+(SingleClass*) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
instance = [[self allocWithZone:NULL] init] ;
}) ;
return instance ;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [SingleClass shareInstance];
}
- (id)copy {
return [SingleClass shareInstance];
}
这样的话,上边的三个对象就完全一样了,及同一个对象
下边也是写单例的一种放法
#import "SingleClass.h"
static SingleClass* instance = nil;
@implementation SingleClass
+(SingleClass*) shareInstance
{
@synchronized(self) {
if(!instance) {
instance = [[SingleClass alloc] init];
}
}
return instance ;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [SingleClass shareInstance];
}
- (id)copy {
return [SingleClass shareInstance];
}
@end