iOS开发单例的严谨写法
2017-12-06 本文已影响77人
因为太有钱
OC 的单例写法
创建对象的步骤分为
1:申请内存(alloc)
2:初始化(init) 这两个步骤
我们要确保对象的唯一性,因此在第一步这个阶段我们就要拦截它。
当我们调用alloc方法时,OC内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法中调用shareInstance方法返回单例对象,这样就可以达到我们的目的。
拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用shareInstance方法返回单例对象。
#import "Single.h"
static Single *single = nil;
@implementation Single
+(instancetype) shareInstance{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
single = [[super allocWithZone:NULL] init];
}) ;
return single ;
}
+(id) allocWithZone:(struct _NSZone *)zone{
return [Single shareInstance] ;
}
-(id) copyWithZone:(struct _NSZone *)zone{
return [Single shareInstance] ;
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@%@",[[Single alloc] init],[Single shareInstance]);
//打印结果:<Single: 0x60400001fdb0><Single: 0x60400001fdb0>
}
可继承单利
可继承单例是指父类中写下单例创建的方法
当其本身类或其子类调用父类中的类创建的方法时, 可以各自类创建各自类的单例. 所以, 在父类中写的一个方法, 同时适用于其本身和其子类, 故称作可继承单例.
#import "Singleton.h"
#import <objc/runtime.h>
@implementation Singleton
+(instancetype)sharedInstance{
id instance = objc_getAssociatedObject(self, @"instance");
if (!instance){
instance = [[super allocWithZone:NULL] init];
NSLog(@"单例创建=====%@=====",instance);
objc_setAssociatedObject(self, @"instance", instance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return instance;
}
+(id) allocWithZone:(struct _NSZone *)zone{
return [self sharedInstance] ;
}
-(id) copyWithZone:(struct _NSZone *)zone{
Class selfClass = [self class];
return [selfClass sharedInstance] ;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//继承单利
NSLog(@"%@%@",[[Inheritance alloc] init],[Inheritance sharedInstance]);
//打印结果 <Inheritance: 0x6040000068a0><Inheritance: 0x6040000068a0>
//再创建继承自 Inheritance 的文件 也能直接创建单利
}
@end
宏 定义一个 单利 文件
#ifndef SingleTone_h
#define SingleTone_h
#define SingleToneH(MethodName) +(instancetype)shared##MethodName
//如果不是ARC的模式下
#if !__has_feature(objc_arc)
#define SingleToneM(MethodName)\
static id _instance = nil;\
+(id)allocWithZone:(struct _NSZone *)zone\
{\
if (_instance == nil) {\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
}\
return _instance;\
}\
-(instancetype)init\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super init];\
});\
return _instance;\
}\
+(instancetype)shared##MethodName\
{\
return [[self alloc] init];\
}\
-(oneway void)release{}\
-(id)retain{return self;}\
-(NSUInteger)retainCount{return 1;}\
#else
#define SingleToneM(MethodName)\
static id _instance = nil;\
+(id)allocWithZone:(struct _NSZone *)zone\
{\
if (_instance == nil) {\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
}\
return _instance;\
}\
-(instancetype)init\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super init];\
});\
return _instance;\
}\
+(instancetype)shared##MethodName\
{\
return [[self alloc] init];\
}
#endif
#endif /* SingleTone_h */
使用的时候 直接创建一个.h文件 把上边代码 粘过去
分别在 .h文件 .m文件 调用相应宏就可以
#import <Foundation/Foundation.h>
#import "SingleTone.h"
@interface MalocSingleTone : NSObject
SingleToneH(Maloc);
@end
#import "MalocSingleTone.h"
@implementation MalocSingleTone
SingleToneM(Maloc)
@end
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%@,%@",[MalocSingleTone sharedMaloc],[[MalocSingleTone alloc] init]);
//打印结果: <MalocSingleTone: 0x604000008820>,<MalocSingleTone: 0x604000008820>
}
老版本中 Swift 仿 OC 的写法
class SharedInstance: NSObject {
static var instance: SharedInstance?
static var onceToken: dispatch_once_t = 0
class func shared() -> SharedInstance {
dispatch_once(&onceToken) { () -> Void in
instance = SharedInstance()
}
return instance!
}
}
现在单利的写法
class NetWork: NSObject {
static let shareNet = NetWork.init()
private override init(){}
}
文章参考: iOS严谨单例写法/可继承单例
代码地址:Github 代码地址