之前太过于年轻,总结的简单单例模式传送门: http://www.cnblogs.com/PSSSCode/p/5482419.html
这篇博客主要讲的是GCD中的单例模式,大家肯定会想到dispatch_once这个函数,但是这篇博客不仅仅是dispatch_once的使用。
1、单例模式简介(面试常考的。。。)
- 单例模式的作用
- 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
- 从而方便地控制了实例个数,并节约系统资源
- 单例模式的使用场合
-
系统
- UIApplication、NSUserDefaults、NSFileManager、NSNoticationCenter
-
自定义
- 在某个应用程序中,共享一份资源(这份资源只需要创建初始化一次)
- 网络计数器
- 分享界面、登录界面、评论界面不登录会跳转到唯一界面登录界面(单例实现)
- 点击跳转,控制器设置为单例,该控制器不会被销毁,依然存在内存中,返回再次回去,再点击进来,则会快速进入不会创建对应的新的控制器
2、具体代码
- 只需实现三个方法
- 1、allocWithZone: (alloc底层调用该方法)
- 2、shareCar (一种命名规范)
-
3、copyWithZone (对应实例变量 调用copy会调用该方法)
默认情况
添加单例情况
1 @interface PSSCar() // <NSCopying> 2 3 @end 4 5 @implementation PSSCar 6 7 static PSSCar *_car; 8 9 + (instancetype)allocWithZone:(struct _NSZone *)zone 10 { 11 static dispatch_once_t onceToken; 12 dispatch_once(&onceToken, ^{ 13 _car = [super allocWithZone:zone]; 14 }); 15 return _car; 16 } 17 18 + (instancetype)sharedCar 19 { 20 static dispatch_once_t onceToken; 21 dispatch_once(&onceToken, ^{ 22 _car = [[self alloc] init]; 23 }); 24 return _car; 25 } 26 27 - (id)copyWithZone:(NSZone *)zone 28 { 29 return _car; 30 }
3、封装代码
当一个项目中多个类需要使用单例,则需要在对应类的.m文件中写以上的代码,并且代码几乎没有差别,所有可以将上面的代码封装成一个工具类,并在工具类中使用宏定义,减少代码冗余。
// .h文件 #define PSSSingletonH(name) + (instancetype)shared##name; // .m文件 #define PSSSingletonM(name) \ static id _instance; \ \ + (instancetype)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [super allocWithZone:zone]; \ }); \ return _instance; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instance = [[self alloc] init]; \ }); \ return _instance; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instance; \ }
在对应类的.h和.m中只需要调用宏定义重新命名的响应方法即可,同时将本类的类名传入,即可实现快速单例模式的实现与使用