问题提出:
在iOS应用的生命周期中,有时候我们只需要某个类的一个实例。
1、单例的实现
// Singleton.h
#import
@interface Singleton :NSObject
+ (instancetype)sharedManager;
@end
// Singleton.m
#import "Singleton.h"
@implementation Singleton
+ (instancetype)sharedManager{
//静态变量
static Singleton*sharedManager = nil;
//dispatch_once 函数由GCD提供,它的作用是整个应用的生命周期block代码块代码只执行一次,并且此运行是线程同步的
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[Singleton alloc] init];
});
return sharedManager;
}
@end
2、从1中可以看出,当我们调用sharedManager方法时获取到的对象是相同的,但是当我们通过alloc、init以及copy来构造对象的时候,依然会创建新的实例。
为了确保对象的唯一性,我们需要封锁用户通过alloc、init以及copy来构造对象这条道路。
创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,要确保对象的唯一性,在第一步这个阶段我们就要拦截。当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法中调用sharedManager方法返回单例对象,这样就可以达到我们的目的。拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用sharedManager方法返回单例对象。
// Singleton.h
#import
@interface Singleton :NSObject
+ (instancetype)sharedManager;
@end
// Singleton.m
#import "Singleton.h"
@interface Singleton ()
@end
@implementation Singleton
+ (instancetype)sharedManager{
//静态变量
static Singleton *sharedManager = nil;
//dispatch_once 函数由GCD提供,它的作用是整个应用的生命周期block代码块代码只执行一次,并且此运行是线程同步的
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//不能使用alloc方法,而要调用[[super allocWithZone:NULL] init]。因为已经重写allocWithZone对象分配方法,所以要借用父类的allocWithZone来帮助内存分配
sharedManager = [[superallocWithZone:NULL] init];
});
return sharedManager;
}
+ (instancetype)allocWithZone:(struct _NSZone*)zone{
return [self sharedManager];
}
- (id)copyWithZone:(NSZone*)zone{
return [Singleton sharedManager];
}
- (id)mutableCopyWithZone:(NSZone*)zone{
return [Singleton sharedManager];
}
@end
网友评论