定义
简单的来说,一个单例类,在整个程序中只有一个实例,并且提供一个类方法供全局调用,在编译时初始化这个类,然后一直保存在内存中,到程序(APP)退出时由系统自动释放这部分内存
系统常用的单例
- UIApplication(应用程序实例类)
- NSNotificationCenter(消息中心类)
- NSFileManager(文件管理类)
- NSUserDefaults(应用程序设置)
- NSURLCache(请求缓存类)
- NSHTTPCookieStorage(应用程序cookies池)
系统很多的单例不能多次创建
比如
[[UIApplication alloc] init];
就会奔溃
image.png
防止单例多次创建,只能创建一次
#import "Person.h"
static Person *_instance;
@implementation Person
/** Person单例 */
+ (instancetype)sharedPerson
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[Person alloc] init];
});
return _instance;
}
/** 重写单例对象的alloc方法, 防止单例对象被重复创建 */
+ (instancetype)alloc
{
if (_instance) {
// 如果单例对象存在则抛出异常
NSException *exception = [NSException exceptionWithName:@"重复创建单例对象异常" reason:@"请使用Person的单例方法." userInfo:nil];
[exception raise];
}
return [super alloc]; // 如果单例对象不存在则正常创建Person
}
//此时单例就已经写好了,只要我们在外面调用shareManager这个方法,返回的对象始终是一个,因为dispatch_once只执行一次。
//但是如果我们不小心调用了alloc、copy、mutablecopy(因为本文的DataManager继承自NSObject,默认DataManager实现了NSCopying,NSMutableCopying协议,否则copy、mutablecopy会导致崩溃) 返回的对象就不是同一个了,因为这些操作会生成新的对象,要保证单例的唯一性就需要重写这些方法
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
// return self; 此处返回self或者manager 打印的对象是同一个,并没有发现什么区别
return _instance;
}
- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {
// return self; 此处返回self或者manager 打印的对象是同一个,并没有发现什么区别
return _instance;
}
单例在程序启动时默认开启
其实是在+load
方法里创建了单例
销毁单例
//1. 必须把static dispatch_once_t onceToken; 这个拿到函数体外,成为全局的.
+(void)attempDealloc{
onceToken = 0; // 只有置成0,GCD才会认为它从未执行过.它默认为0.这样才能保证下次再次调用shareInstance的时候,再次创建对象.
_instance = nil;
}
网友评论