在一个iOS应用的生命周期中,有时候我们只需要某个类的一个实例。例如当程序启动时,应用的状态由UIApplication类的一个实例维护,这个实例代表了整个应用程序对象,它只能是一个实例,作用是实现应用程序中一些共享资源的访问和状态的保持。
下面就是一个单例类的例子
#import "DDZPerson.h" @interface DDZPerson ()<NSCopying> @end @implementation DDZPerson static DDZPerson *_person; //实现单例模式,先重写allocWithZone + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //只执行一次 _person = [super allocWithZone:zone]; }); return _person; } //为了方便用户直接调用 + (instancetype)sharedPerson { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _person = [[self alloc] init]; }); return _person; } //实现可以copy的方法 - (id)copyWithZone:(NSZone *)zone { return _person; } @end
因为基本上所有的类单例模式都差不多
所以完全可以将他们定义在一个宏文件中
#define DDZSingletonH + (instancetype)sharedInstance; #define DDZSingletonM static id *_instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } + (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (id)copyWithZone:(NSZone *)zone { return _instance; }
在后面敲 的原因是因为,宏定义只识别最近的一行
只有敲了 之后才会继续识别
补充:如果你想要自定义方法名,可以这么做
#define DDZSingletonH(name) + (instancetype)shared##name;
根据传进来的name来定义方法名sharedname;