本文首先实现单例模式,然后对单例代码进行抽取宏,使其他类可以一句代码实现单例(只介绍ARC环境)
本文代码
- 单例介绍
- 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
- 从而方便地控制了实例个数,并节约系统资源
- 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)
- 单例实现
以代码中的Book类为例
首先要在.h文件中提供外部访问方法
+ (instancetype)sharedBook;
然后是.m文件中实现这个方法
static HXBook *_book;
+ (instancetype)sharedBook
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_book = [[self alloc] init];
});
return _book;
}
我们知道,新建对象的时候调用alloc和init方法
在alloc中,系统为我们的对象分配了内存
在系统内部,alloc默认调用了allocWithZone
所以,实现单例要重写这两个方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_book = [super allocWithZone:zone];
});
return _book;
}
- (id)copyWithZone:(NSZone *)zone{
return _book;
}
单例已经完成了,测试一下效果:
HXBook *book1 = [[HXBook alloc]init];
HXBook *book2 = [HXBook sharedBook];
HXBook *book3 = [[HXBook alloc]init];
NSLog(@"\n%p\n%p\n%p",book1,book2,book3);
打印结果:
2017-07-10 15:39:35.297 HXSingleton[1529:400378]
0x608000005bf0
0x608000005bf0
0x608000005bf0
内存地址是一样的,完成.
- 对单例抽取宏
新建文件HXSingleton.h
首先对需要做单例类的.h文件抽取宏
name是需要传入的名字
// .h文件
#define HXSingletonH(name) + (instancetype)shared##name;
然后是.m文件的抽取
// .m文件
#define HXSingletonM(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; \
}
#######宏的使用
新建HXPen类
.h中这么写:
#import <Foundation/Foundation.h>
#import "HXSingleton.h"
@interface HXPen : NSObject
HXSingletonH(Pen)
@end
.m中这么写
@implementation HXPen
HXSingletonM(Pen)
@end
完成!
测试一下:
HXPen *pen1 = [[HXPen alloc]init];
HXPen *pen2 = [HXPen sharedPen];
HXPen *pen3 = [[HXPen alloc]init];
NSLog(@"\n%p\n%p\n%p",pen1,pen2,pen3);
打印结果:
2017-07-10 15:44:54.380 HXSingleton[1564:431889]
0x608000008ed0
0x608000008ed0
0x608000008ed0
内存是一样的,完成!
感谢阅读
你的支持是我写作的唯一动力