1 static DemoObj *instance; 2 3 /** 4 1. 重写allocWithZone,用dispatch_once实例化一个静态变量 5 2. 写一个+sharedXXX方便其他类调用 6 */ 7 8 // 在iOS中,所有对象的内存空间的分配,最终都会调用allocWithZone方法 9 // 如果要做单例,需要重写此方法10 // GCD提供了一个方法,专门用来创建单例的11 + (id)allocWithZone:(struct _NSZone *)zone12 {13 static DemoObj *instance;14 15 // dispatch_once是线程安全的,onceToken默认为016 static dispatch_once_t onceToken;17 // dispatch_once宏可以保证块代码中的指令只被执行一次18 dispatch_once(&onceToken, ^{19 // 在多线程环境下,永远只会被执行一次,instance只会被实例化一次20 instance = [super allocWithZone:zone];21 });22 23 return instance;24 }25 26 + (instancetype)sharedDemoObj27 {28 // 如果有两个线程同时实例化,很有可能创建出两个实例来29 // if (!instance) {30 // // thread 1 0x0000A31 // // thread 2 0x0000B32 // instance = [[self alloc] init];33 // }34 // // 第一个线程返回的指针已经被修改!35 // return instance;36 return [[self alloc] init];37 }38 39 40 单例的宏41 42 // .h43 #define singleton_interface(class) + (instancetype)shared##class;44 45 // .m46 #define singleton_implementation(class) \47 class *_instance; \48 \49 + (id)allocWithZone:(struct _NSZone *)zone \50 { \51 static dispatch_once_t onceToken; \52 dispatch_once(&onceToken, ^{ \53 _instance = [super allocWithZone:zone]; \54 }); \55 \56 return _instance; \57 } \58 \59 + (instancetype)shared##class \60 { \61 if (_instance == nil) { \62 _instance = [[class alloc] init]; \63 } \64 \65 return _instance; \66 }