💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
单例模式的作用:可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源。 单例模式的使用场合: 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)。 ##一:单例模式 - ARC: 1、在.m中保留一个全局的static的实例(static 防止其它类extern引用 修改值) staticid _instance; 2、重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全) ~~~ + (id)allocWithZone:(struct_NSZone *)zone {     if (_instance ==nil) { //防止频繁加锁        @synchronized(self) {            if (_instance ==nil) { //防止创建多次   _instance = [superallocWithZone:zone];             }         }     }     return_instance; } ~~~ 3、提供1个类方法让外界访问唯一的实例 ~~~ + (instancetype)sharedMusicTool {     if (_instance ==nil) { //防止频繁加锁        @synchronized(self) {            if (_instance ==nil) { //防止创建多次               _instance = [[selfalloc] init];             }         }     }     return_instance; } ~~~ 4、实现copyWithZone:方法 ~~~ - (id)copyWithZone:(struct_NSZone *)zone {     return_instance; } ~~~ 5、如果要实现饿汉式的单例,就实现load方法。(建议不使用) //当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次) ~~~ +(void)load{     _instance = [[self alloc] init]; } ~~~ 音乐单例工具类例子代码: MusicTool.h ~~~ #import <UIKit/UIKit.h> @interface MusicTool : UIView //提供1个类方法让外界访问唯一的实例 +(instancetype)sharedMusicTool; @end ~~~ MusicTool.m ~~~ #import "MusicTool.h" //单例模式:懒汉式 @implementation MusicTool static id _instance; //static 防止其它类extern引用 修改值 /** * 如果要实现饿汉式的单例,就实现load方法 * 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次) */ //+(void)load{ // _instance = [[self alloc] init]; //} //当第一次使用这个类的时候才会调用 //+(void)initialize{ // NSLog(@"===initialize==="); //} /** * alloc 方法内部会调用这个方法 */ +(id)allocWithZone:(struct _NSZone *)zone{ if (_instance == nil) {//防止频繁加锁 @synchronized(self) { if (_instance == nil) {//防止创建多次 _instance = [super allocWithZone:zone]; } } } return _instance; } /** * 实例化类 */ +(instancetype)sharedMusicTool{ if (_instance == nil) {//防止频繁枷锁 @synchronized(self) { if (_instance == nil) {//防止创建多次 _instance = [[self alloc] init ]; } } } return _instance; } /** * 重写copy方法,保证copy出来的也是单例类 */ -(id)copyWithZone:(NSZone *)zone{ return _instance; } @end ~~~ ##二:单例模式 – 非ARC 非ARC中(MRC),单例模式的实现(比ARC多了几个步骤) 实现内存管理方法 ~~~ - (id)retain {returnself; } - (NSUInteger)retainCount {return1; } - (onewayvoid)release {} - (id)autorelease {returnself; } ~~~ MusicTool.m ~~~ #import "MusicTool.h" @implementation MusicTool static id _instance; //static 防止其它类extern引用 修改值 /** * 如果要实现饿汉式的单例,就实现load方法 * 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次) */ //+(void)load{ // _instance = [[self alloc] init]; //} //当第一次使用这个类的时候才会调用 //+(void)initialize{ // NSLog(@"===initialize==="); //} /** * alloc 方法内部会调用这个方法 */ +(id)allocWithZone:(struct _NSZone *)zone{ if (_instance == nil) {//防止频繁加锁 @synchronized(self) { if (_instance == nil) {//防止创建多次 _instance = [super allocWithZone:zone]; } } } return _instance; } /** * 实例化类 */ +(instancetype)sharedMusicTool{ if (_instance == nil) {//防止频繁枷锁 @synchronized(self) { if (_instance == nil) {//防止创建多次 _instance = [[self alloc] init ]; } } } return _instance; } /** * 重写copy方法,保证copy出来的也是单例类 */ -(id)copyWithZone:(NSZone *)zone{ return _instance; } //重写release方法,不释放 -(oneway void)release{ } //重写retain方法,返回单例类 -(instancetype)retain{ return self; //return _instance; } //计算永远为1 -(NSUInteger)retainCount{ return 1; } @end ~~~ 测试: ~~~ MusicTool *mt1 = [[MusicTool alloc] init]; MusicTool *mt2 = [MusicTool sharedMusicTool]; MusicTool *mt3 = [mt2 copy]; [mt2 release];//非arc环境下release NSLog(@"==%@==%@==%@",mt1,mt2,mt3); ~~~ ![](https://box.kancloud.cn/2016-03-07_56dd40104f8b1.jpg) ##三:单例模式在ARC\MRC环境下的写法有所不同,可以用宏判断是否为ARC环境 ~~~ #if __has_feature(objc_arc) // ARC #else // MRC #endif ~~~ 把单例定义成宏,抽出公共类 1、HMSingleton.h ~~~ // .h文件 #define HMSingletonH(name) + (instancetype)shared##name; // .m文件 #if __has_feature(objc_arc) #define HMSingletonM(name) \ static id _instace; \ \ + (id)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [super allocWithZone:zone]; \ }); \ return _instace; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [[self alloc] init]; \ }); \ return _instace; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instace; \ } #else #define HMSingletonM(name) \ static id _instace; \ \ + (id)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [super allocWithZone:zone]; \ }); \ return _instace; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [[self alloc] init]; \ }); \ return _instace; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instace; \ } \ \ - (oneway void)release { } \ - (id)retain { return self; } \ - (NSUInteger)retainCount { return 1;} \ - (id)autorelease { return self;} #endif ~~~ 2、要想再整个项目中都能使用这个宏,则要在预编译pch文件中import导入这个头文件 ~~~ #ifdef __OBJC__     #import <UIKit/UIKit.h>     #import <Foundation/Foundation.h> #import"HMSingleton.h" #endif ~~~     ps:xcode7添加pch文件参考之前的文章[http://blog.csdn.net/zhixinhuacom/article/details/49564315](http://blog.csdn.net/zhixinhuacom/article/details/49564315) 3、使用HMSingleton工具类,实现HMMusicTool单例 HMMusicTool.h ~~~ #import <Foundation/Foundation.h> @interface HMMusicTool : NSObject //宏定义的方法 HMSingletonH(MusicTool) @end ~~~ HMMusicTool.m ~~~ #import "HMMusicTool.h" @implementation HMMusicTool //宏定义的方法 HMSingletonM(MusicTool) @end ~~~ 4.测试: ~~~ HMMusicTool *tool1 = [HMMusicTool sharedMusicTool]; HMMusicTool *tool2 = [HMMusicTool sharedMusicTool]; HMMusicTool *tool3 =[[HMMusicTool alloc]init]; HMMusicTool *tool4 =[tool3 copy]; NSLog(@"%@", tool1); NSLog(@"%@", tool2); NSLog(@"%@", tool3); NSLog(@"%@", tool4); ~~~ ![](https://box.kancloud.cn/2016-03-07_56dd40106ce82.jpg)