最近公司项目其中的一个控制器需要做成单例,以保证收到推送或应用内消息时弹出的是同一个界面,看了下相关资料和视频,现把ios实现单例的几种方式总结一下:
dispatch
这种方式个人认为是最简单、最方便、最推荐的方式,且能够保证线程安全。缺点就是只能在ARC环境使用,非ARC方式不能使用
- 定义一个
类方法声明
的宏LGSingletonH,并传入要创建单例的类名
#import <UIKit/UIKit.h>
@interface LGSingleton : NSObject
//******************************** 将类方法声明宏,传入类名 ********************************
#define LGSingletonH(ClassName) +(instancetype) share##ClassName;
@end
- 再将单例实现的具体方法定义为一个宏LGSingletonM
@implementation LGSingleton
//********************************* 将方法的实现声明为宏 **********************************
#define LGSingletonM(ClassName) static id _instance;\
\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
\
return _instance;\
}\
\
\
+(instancetype)share##ClassName\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [[self alloc] init];\
});\
\
return _instance;\
}\
\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}
@end
使用方法:
- 在要创建单例的类的
.h
文件中,导入单例工具类LGSingleton.h
头文件
- 在要创建单例的类的
.h
文件中,直接写LGSingletonH宏并传入类名即可
Tips:LGSingletonH(Person)等价于+(instancetype) sharePerson;
- 在要创建单例的类的
.m
文件中,实现单例方法,也就是直接写我们定义的LGSingletonM宏并传入对应类名即可。
Tips:LGSingletonM(Person)宏等价于将我们在单例工具类LGSingleton中写的实现方法在要创建的单例类Person中复制了一遍,也即是将Person类的allocWithZone和copyWithZone方法重写了一遍,并提供了一个类方法创建单例
-
测试效果:
- LGSingleton.h文件下载:Github,直接将文件放入工程即可使用