做用:能够保证在程序运行过程,一个类只有一个实例,并且该实例易于外界访问atom
#import "MusicTool.h" @interface HMMusicTool () @property (strong, nonatomic) NSMutableArray *music; //.h @end @implementation MusicTool -(NSArray *)music { if (_music == nil) { _music = [NSMutableArray array]; } return _music; } static id _musicTool; + (id)allocWithZone:(struct _NSZone *)zone { if (_musicTool == nil){ //避免屡次加锁 @synchronized(self) { //加锁,避免屡次加载 if (_musicTool == nil) { // 防止建立屡次 _musicTool = [super allocWithZone:zone]; } } } return _musicTool; } +(instancetype)shareMusiclTool { if (_musicTool == nil){ //避免屡次加锁 @synchronized(self){ if (_musicTool == nil) { _musicTool = [[self alloc] init]; } } } return _musicTool; } - (id)copyWithZone:(NSZone *)zone { return _musicTool; } #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; MusicTool *tool = [[MusicTool alloc] init]; MusicTool *tool1 = [[MusicTool alloc] init]; MusicTool *tool2 = [MusicTool shareMusiclTool]; MusicTool *tool3 = [tool1 copy]; NSLog(@"%p %p %p %p",tool.music,tool1.music,tool2.music,tool3.music); //返回的结果都是相同的指针,全部只有一个实例 }
/** * 当类加载到OC运行环境中(内存),就会调用一次 */ + (void)load { _moiveTool = [[self alloc] init]; } /** * 当第一次使用这个类的时候才会调用 */ + (void)initialize { NSLog(@"-------initialize"); } + (instancetype)allocWithZone:(struct _NSZone *)zone { /** * load当即调用alloc,因此不须要加锁 */ if (_moiveTool == nil) {//防止频繁alloc return [super allocWithZone:zone]; } return _moiveTool; } + (instancetype)shareMoiveTool { return _moiveTool; } - (id)copyWithZone:(NSZone *)zone { return _moiveTool; }
#import "SingTool.h" @implementation SingTool //用来保存惟一的单例对象 static id _instance; +(instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } +(instancetype)shareSingTool { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } //copy多是已存在_instance,因此直接返回 -(id)copyWithZone:(NSZone *)zone { return _instance; }
#import "SingTool.h" @implementation SingTool //用来保存惟一的单例对象 static id _instance; +(instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } +(instancetype)shareSingTool { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } //copy多是已存在_instance,因此直接返回 -(id)copyWithZone:(NSZone *)zone { return _instance; } //重写release,retain,retainCount,autorelease方法 //重写release,执行release时候不进行操做 -(oneway void)release { } - (instancetype)retain { return self; } -(NSUInteger)retainCount { return 1; } -(instancetype)autorelease { return self; }
1,直接用宏定义文件,无需额外本身写 //GCD //.h文件 #define SingletionH(name) +(instancetype)share##name; //.m文件 #if __has_feature(objc_arc) #define SingletionM(name) \ static id _instance; \ \ +(instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [super allocWithZone:zone]; \ }); \ return _instance; \ } \ \ +(instancetype)share##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[self alloc] init]; \ }); \ return _instance; \ } \ \ -(id)copyWithZone:(NSZone *)zone \ { \ return _instance; \ } #else #define SingletionM(name) \ static id _instance; \ \ +(instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [super allocWithZone:zone]; \ }); \ return _instance; \ } \ \ +(instancetype)share##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[self alloc] init]; \ }); \ return _instance; \ } \ \ -(id)copyWithZone:(NSZone *)zone \ { \ return _instance; \ } \ -(oneway void)release \ { \ \ } \ - (instancetype)retain \ { \ return self; \ } \ -(NSUInteger)retainCount \ { \ return 1; \ } \ -(instancetype)autorelease \ { \ return self; \ } #endif
#if __has_feature(objc_arc) //编译器是ARC环境 NSLog(@"ARC环境"); #else //编译器是MRC环境 NSLog(@"MRC环境"); #endif }