单利平时开发中用的比较多,写一个通用安全的单利是很有必要的
因为单例具有唯一性,要保证每个创建的类是不同的,所以在每个类生成时,我们动态的给类绑定唯一的对象。
使用runTime的关联对象进行创建。
#import "ShareSingle.h"
#import <objc/runtime.h>
@implementation ShareSingle
/** 单例对象 */
+ (instancetype)shareSingle {
// 获取当前对象的类
Class selfClass = [self class];
// 从类中获取对象
id instance = objc_getAssociatedObject(selfClass, @"shareSingle");
@synchronized (self) {
if (!instance) {
// 不存在,创建对象
instance = [[super allocWithZone:NULL] init];
// 给类绑定对象
objc_setAssociatedObject(selfClass, @"shareSingle", instance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
return instance;
}
/** 保证alloc、init也创建同样的对象 */
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
// 获取当前对象的类
Class class = [self class];
// 返回当前类绑定的对象
return [class shareSingle];
}
- (id)copyWithZone:(struct _NSZone *)zone
{
return [[self class] shareSingle] ;
}
@end
@implementation Student
@end
@implementation Teacher
@end
在ViewController中测试如下:
- (void)viewDidLoad {
[super viewDidLoad];
Teacher *objc = [Teacher shareSingle];
NSLog(@"%p", objc);
Teacher *objc2 = [[Teacher alloc] init];
NSLog(@"%p", objc2);
Student *subObjc = [Student shareSingle];
NSLog(@"%p", subObjc);
Student *subObjc2 = [[Student alloc] init];
NSLog(@"%p", subObjc2);
}
测试结果,可以看到无论使用什么方法创建单利,都是同一个对象,并且父类和子类是不同的对象
2019-04-01 10:20:11.336438+0800 Test[98811:3950790] 0x600000200310
2019-04-01 10:20:11.336576+0800 Test[98811:3950790] 0x600000200310
2019-04-01 10:20:11.336711+0800 Test[98811:3950790] 0x60400020a840
2019-04-01 10:20:11.336786+0800 Test[98811:3950790] 0x60400020a840
网友评论