iOS 开发技巧iOS开发知识小集首页投稿(暂停使用,暂停投稿)

iOS单例一行实现(抽取单例宏)

2017-07-10  本文已影响339人  王技术

本文首先实现单例模式,然后对单例代码进行抽取宏,使其他类可以一句代码实现单例(只介绍ARC环境)
本文代码

- 单例介绍
- 单例实现

以代码中的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

内存是一样的,完成!

谢谢阅读
有不合适的地方请指教
喜欢请点个赞
抱拳了!

上一篇 下一篇

猜你喜欢

热点阅读