22day 单例模式
来源:互联网 发布:2016淘宝客如何推广 编辑:程序博客网 时间:2024/06/13 12:42
1、单例模式的基本实现
/** 单例模式:一个类只有一个对象 */@implementation HLMusicToolid _musicTool;//全局变量/** alloc方法内部会调用这个方法 */+ (instancetype)allocWithZone:(struct _NSZone *)zone{ NSLog(@"%s",__func__); @synchronized(self) {//多线程 //创建对象的内存空间 if (nil == _musicTool) { _musicTool = [super allocWithZone:zone]; } } return _musicTool;}/** 方便访问单例对象*/+ (instancetype)sharedMusicTool{ @synchronized(self) { //操作共享资源 if (nil == _musicTool) { _musicTool = [[self alloc]init]; } } return _musicTool;}/** NSLog(@"%@",[[[HLMusicTool alloc]init] copy]);//Returns the object returned by copyWithZone:. copyWithZone 遵守协议NSCopying*/- (id)copyWithZone:(nullable NSZone *)zone{ return _musicTool;}
2、单例模式的完善
解决:
1)extern 对全局变量的引用 :,会在全程序中查找 _musicTool,:在其他类引用全局变量,其他类就可以修改全局变量的值,导致单例对象存在被修改的风险
解决办法就是使用static 进行修饰
2)防止多次加锁: 只有在确实需要创建对象的时候,才进行加锁。即加锁之前先进行是否满足创建对象的条件
/* static 修饰变量: 1)static的局部变量:保证只初始化一次,在程序运行过程中只有一份内容;--局部变量的生命周期和全局变量类似,但是不能改变作用域 2)static 修饰的全局变量:不允许本类的h文件访问。即作用域仅限于当前的文件 ps:在其他类引用全局变量,其他类就可以修改全局变量的值,导致单例对象存在被修改的风险 extern id _musicTool; 引用全局变量,会在全程序中查找 _musicTool 解决方法:static 修饰的全局变量,这样其他类就无法引用extern*/ static id _musicTool;//全局变量/** alloc方法内部会调用这个方法 */+ (instancetype)allocWithZone:(struct _NSZone *)zone{ NSLog(@"%s",__func__); if (nil == _musicTool) { @synchronized(self) {//多线程 //创建对象的内存空间 if (nil == _musicTool) { _musicTool = [super allocWithZone:zone]; } } } return _musicTool;}/** 方便放回单例对象*/+ (instancetype)sharedMusicTool{ if (_musicTool == nil) {//防止频繁加锁 //加锁 @synchronized(self) { //操作共享资源 if (nil == _musicTool) {//防止创建多次 _musicTool = [[self alloc]init]; } } } return _musicTool;}/** NSLog(@"%@",[[[HLMusicTool alloc]init] copy]);//Returns the object returned by copyWithZone:. copyWithZone 遵守协议NSCopying*/- (id)copyWithZone:(nullable NSZone *)zone{ return _musicTool;}
3、GCD和宏实现单例-- 宏定义的代码不好调试
1).ARC 环境下的GCD实现单例
/*GCD 实现单例*/static id _dataTool;+ (instancetype)shareDataTool{ //GCD static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{//一次性代码 _dataTool = [[self alloc]init]; }); return _dataTool;}+ (instancetype)allocWithZone:(struct _NSZone *)zone{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _dataTool = [super allocWithZone:zone]; }); return _dataTool;}- (id)copyWithZone:(NSZone *)zone{ return _dataTool;}
2)、非ARC的单例模式
release重写,进行阻止单例对象的释放
@implementation HSDataToolstatic id _dataTool;+(instancetype)shareDataTool{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _dataTool = [[HSDataTool alloc]init]; }); return _dataTool;}- (id)copyWithZone:(NSZone *)zone{ return _dataTool;}+ (instancetype)allocWithZone:(struct _NSZone *)zone{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _dataTool = [super allocWithZone:zone]; NSLog(@"%s",__func__); }); return _dataTool;}#pragma mark - MRC环境的适配:重写/* Decrements the receiver’s reference count. The receiver is sent a dealloc message when its reference count reaches 0. */- (oneway void)release{}- (instancetype)retain{ return self;}- (NSUInteger)retainCount{ return 1;}
3.GCD和宏 来实现单例
#ifndef HSSingleton_h#define HSSingleton_h//头文件的单例内容#define HSSingletonH(classname) +(instancetype)share##classname//.m文件的单例代码#define HSSingletonM(classname) \static id _instance;\+(instancetype)share##classname{\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [[self alloc]init];\ });\ return _instance;\}\- (id)copyWithZone:(NSZone *)zone{\ return _instance;\}\+ (instancetype)allocWithZone:(struct _NSZone *)zone{\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [super allocWithZone:zone];\ });\ return _instance;\}\- (oneway void)release{\}\- (instancetype)retain{\ return self;\}\- (NSUInteger)retainCount{\ return 1;\}#endif /* HSSingleton_h */
4、ARC、MRC的适配(条件编译)
//头文件的单例内容#define HSSingletonH(classname) +(instancetype)share##classname//.m文件的单例代码#if __has_feature(objc_arc)#define HSSingletonM(classname) \static id _instance;\+(instancetype)share##classname{\static dispatch_once_t onceToken;\dispatch_once(&onceToken, ^{\_instance = [[self alloc]init];\});\return _instance;\}\- (id)copyWithZone:(NSZone *)zone{\return _instance;\}\+ (instancetype)allocWithZone:(struct _NSZone *)zone{\static dispatch_once_t onceToken;\dispatch_once(&onceToken, ^{\_instance = [super allocWithZone:zone];\});\return _instance;\}#else#define HSSingletonM(classname) \static id _instance;\+(instancetype)share##classname{\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [[self alloc]init];\ });\ return _instance;\}\- (id)copyWithZone:(NSZone *)zone{\ return _instance;\}\+ (instancetype)allocWithZone:(struct _NSZone *)zone{\ static dispatch_once_t onceToken;\ dispatch_once(&onceToken, ^{\ _instance = [super allocWithZone:zone];\ });\ return _instance;\}\- (oneway void)release{\}\- (instancetype)retain{\ return self;\}\- (NSUInteger)retainCount{\ return 1;\}\- (instancetype)autorelease{\ return self;\}#endif
5、、饿汉式(了解)
/* ninitailize、load方法的区别: initailize、load都是类方法 当一个类 或者分类被装载进内存时,就会调用一次load方法(当时这个类还不可用) 当第一次使用这个类时,就会调用一次initailize方法*//** Invoked whenever a class or category is added to the Objective-C runtime; 因此不存在多线程问题*/+ (void)load{ _instance = [[HLSoundTool alloc]init]; NSLog(@"%s----instance%@",__func__,_instance);}//+ (void)initialize{// NSLog(@"%s",__func__);//}+ (instancetype)allocWithZone:(struct _NSZone *)zone{ if (_instance == nil) { _instance = [super allocWithZone:zone]; } return _instance;}- (id)copyWithZone:(NSZone *)zone{ return _instance;}+(instancetype)shareSoundTool{ return _instance;}
阅读全文
0 0
- 22day 单例模式
- day day up--Java设计模式之单例模式
- java study 06day--单例设计模式
- 《从零开始学Swift》学习笔记(Day 63)——Cocoa Touch设计模式及应用之单例模式
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 单例模式 2017.12.22作业
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- Java Exception处理逻辑
- informatica数据迁移之Sybase2Oracle
- 安卓开发 易源数据Demo
- 【动态规划23】hdu5036 Explosion(bitset优化)
- mongodb——数据库增删改查
- 22day 单例模式
- 查看APK的签名信息
- wordpress后台创建页面时属性无“模板”选项的问题
- 欧几里得算法
- NodeJs开发环境搭建之Visual Studio Code(二)
- java中String比大小
- 【Sublime】Sublime Text 3 最新可用注册码(免破解)
- HDU4985
- 控制反转与依赖注入