来源:http://www.cnblogs.com/PSSSCode/p/5559865.html
之前太过于年轻,总结的简单单例模式传送门: 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中只需要调用宏定义重新命名的响应方法即可,同时将本类的类名传入,即可实现快速单例模式的实现与使用

本文深入探讨GCD中的单例模式实现,介绍单例模式的作用及应用场景,并提供具体的代码实现,包括如何利用dispatch_once确保实例唯一性,以及通过宏定义简化多个类的单例模式实现。

被折叠的 条评论
为什么被折叠?



