ios单例

工作中经常使用到单例,但通常为了方便只是提供了一个类方法shareXXX(xxx类名),在share中使用dispatch_once来实现单例,该种方式在独立开发中使用问题倒不大,如果提供给第三方使用时,就会出现问题了。会造成非单例的情况,通常都是重写allocWithZone方法,在改方法中实现单例,并且实现copy协议的copyWithZone和mutableCopyWithZone方法完善单例的实现,下面为ARC模式下单例示例

@implementation ARCSingleleModel
// 使用全局变量 可以自定义方法来销毁单例模式,从而下次再次创建是能够正常创建
static ARCSingleleModel *_instance;
static dispatch_once_t onceToken;
+(instancetype)shareArcSingle{
    return [[self alloc]init];
}
//alloc 底层调用还是 allocWithZone,所以重写allocWithZone方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
// copy 方法 也会创建新的对象。为了严谨也应该重写copy方法,因copy方法最终调用的也是copyWithZone因此 重写copyWithZone和mutableCopyWithZone。mutableCopyWithZone,mutableCopyWithZone需遵守NSCopying,NSMutableCopying协议才能敲出,在写出这两个方法后可删除NSCopying,NSMutableCopying协议
-(id)copyWithZone:(NSZone *)zone{
    
  
    return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}
//销毁单例
-(void)destory{
    _instance = nil;
    onceToken = 0;
}
@end

下例是MRC示例,mrc下和arc下单例区别只是重写了retainCount,release,retain三个方法

// 使用全局变量 可以自定义方法来销毁单例模式,从而下次再次创建是能够正常创建
static MRCSingleModel *_instance;
static dispatch_once_t onceToken;
+(instancetype)shareMRCSingleModel{
    return [[self alloc]init];
}
//alloc 底层调用还是 allocWithZone,所以重写allocWithZone方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}
// copy 方法 也会创建新的对象。为了严谨也应该重写copy方法,因copy方法最终调用的也是copyWithZone因此 重写copyWithZone和mutableCopyWithZone。mutableCopyWithZone,mutableCopyWithZone需遵守NSCopying,NSMutableCopying协议才能敲出,在写出这两个方法后可删除NSCopying,NSMutableCopying协议
-(id)copyWithZone:(NSZone *)zone{
    
  
    return _instance;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return _instance;
}
-(void)destory{
    _instance = nil;
    onceToken = 0;
}

#if __has_feature(objc_arc)
//满足 arc
#else
//mrc 重写retain和relase方法就可以
-(oneway void)release{
    
}
- (instancetype)retain{
    return _instance;
}
//习惯 在mrc情况下,实现单例 通常会重写retainCount并返回最大值
-(NSUInteger)retainCount{
    return  MAXFLOAT;
}
#endif


@end

如果工程中要创建多个不同类型的单例,每个都重写上面的方法将会很浪费时间,使用宏定义的方式,可以解决,下面为宏定义的实例,只要在要实现的类中引用该宏,.h文件使用SingleH方法,.m文件中使用SingleM

#ifndef Single_h
#define Single_h
#define SingleH(name)  +(instancetype)share##name;


#if __has_feature(objc_arc)
#define SingleM(name) static id _instance;\
static dispatch_once_t onceToken;\
+(instancetype)share##name{\
    return [[self alloc]init];\
}\
+ (instancetype)allocWithZone:(struct _NSZone *)zone{\
    dispatch_once(&onceToken, ^{\
        _instance = [super allocWithZone:zone];\
    });\
    return _instance;\
}\
-(id)copyWithZone:(NSZone *)zone{\
    return _instance;\
}\
-(id)mutableCopyWithZone:(NSZone *)zone{\
    return _instance;\
}\
-(void)destory{\
    _instance = nil;\
    onceToken = 0;\
}
//满足 arc
#else
#define SingleM(name) static id _instance;\
static dispatch_once_t onceToken;\
+(instancetype)share##name{\
    return [[self alloc]init];\
}\
+ (instancetype)allocWithZone:(struct _NSZone *)zone{\
    dispatch_once(&onceToken, ^{\
        _instance = [super allocWithZone:zone];\
    });\
    return _instance;\
}\
-(id)copyWithZone:(NSZone *)zone{\
    return _instance;\
}\
-(id)mutableCopyWithZone:(NSZone *)zone{\
    return _instance;\
}\
-(void)destory{\
    _instance = nil;\
    onceToken = 0;\
}\
-(oneway void)release{\
}\
- (instancetype)retain{\
    return _instance;\
}\
-(NSUInteger)retainCount{\
    return  MAXFLOAT;\
}
#endif


#endif /* Single_h */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值