单例设计模式以及单例宏抽取

  • 什么是单例
    一个类只允许有一个实例,在整个程序中需要多次使用,共享同一份资源的时候,就可以创建单例,一般封装成工具类使用,苹果封装成单例常用的

  • 什么情况下使用单例

    1. 类只能有一个实例,并且必须从一个为人熟知的访问点对其进行访问,比如类工厂方法
    2. 这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端的代码
  • 设计要点

    1. 某个类只有一个实例
    2. 必须自行创建这个对象
    3. 必须自行向整个系统提供这个实例
    4. 这个方法一定是一个静态类
ARC中
+ (instancetype)shareInstance
{
    Tools *instance = [[self alloc] init];
    return instance;
}
//创建一个全局变量,控制对象只调用一次
static Tools *_instance = nil;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    //所有的创建方法都会调用该方法,只需要在这里控制当前对象之创建一次即可
    if (_instance == nil) {
        _instance = [[super allocWithZone:zone] init];
    }
    return _instance;
}
//用到copy要给类加协议,因为是单例,所以直接返回就行了
- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}

但是该方法在多线程中会出毛病,只需要在重写allocWithZone中这样修改

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    //再多线程中也只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}
MRC

只需要多重写release,retain,retainCount

- (oneway void)release
{
    //需要让程序在整个过程中只有一个实例,什么都不做
}

- (instancetype)retain
{
    return _instance;
}

- (NSUInteger)retainCount
{
    //方便沟通,不会返回1,返回一个巨大的值
    return MAXFLOAT;
}

单例宏抽取

反斜杠代表一行

#define interfaceSingleton(name) +(instancetype)share##name
//判断是ARC还是MRC
#if __has_feature(objc_arc)

#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static  name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \

#else

#define implementationSingleton(name) \
+ (instancetype)share##name \
{ \
name *instance = [[self alloc] init]; \
return instance; \
} \
static  name *_instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[super allocWithZone:zone] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone \
{ \
return _instance; \
} \
- (oneway void)release \
{ \
} \
- (instancetype)retain \
{ \
return _instance; \
} \
- (NSUInteger)retainCount \
{ \
return MAXFLOAT; \
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值