单例模式的实现(ARC与非ARC)

 单例模式是一种很重要的设计模式,在iOS开发中,通过使用单例设计模式来实现在程序生命周期内只有一个实例存在来节省内存开销。
下面是ARC中单例模式的实现代码:
在自定义的类.m文件中,需要实现下列的方法
#import "HMAudioTool.h"

@interface HMAudioTool ()
@end

@implementation HMAudioTool
定义一份变量 ( 整个程序运行过程中 , 只有 1 )
static id _instance;

- (
id )init
{
   
if ( self = [ super init ]) {
       
static dispatch_once_t onceToken;
       
dispatch_once (&onceToken, ^{
           
// 加载资源
           
        });
    }
   
return self ;
}

/**
 * 
重写这个方法 : 控制内存内存
 */

+ (
id )allocWithZone:( struct _NSZone *)zone
{
   
// 里面的代码永远只执行 1
   
static dispatch_once_t onceToken;
   
dispatch_once (&onceToken, ^{
       
_instance = [ super allocWithZone :zone];
    });
   
   
// 返回对象
   
return _instance ;
}

+ (
instancetype )sharedAudioTool
{
   
// 里面的代码永远只执行 1
   
static dispatch_once_t onceToken;
   
dispatch_once (&onceToken, ^{
       
_instance = [[ self alloc ] init ];
    });
   
   
// 返回对象
   
return _instance ;
}

@end

通过重写allocWithZone,copyWithZone,以及init方法来实现在内存中只存在一个HMAudioTool对象.
上面的代码是ARC下单例的实现,而对于非ARC而言,还需要重写release,autorelease,retain,retainCount来保证返回的对象为单例,代码如下:
+ ( id )copyWithZone:( struct _NSZone *)zone
{
   
return _instance ;
}

- (
oneway void )release
{
   
}

- (
instancetype )autorelease
{
   
return _instance ;
}

- (
instancetype )retain
{
   
return _instance ;
}

- (
NSUInteger )retainCount
{
   
return 1 ;
}
通过重写上面五个方法来确保单例对象在非ARC下存在。
实际开发中,我们可以将这些代码抽取到一个头文件里面以宏定义的方式来调用.

// ## : 连接字符串和参数
#define singleton_h(name) + (instancetype)shared##name;

#if __has_feature(objc_arc) // ARC

#define singleton_m(name) \
static id _instance; \
+ (id)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:( struct _NSZone *)zone \
{ \
   
return _instance; \
}

#else // ARC

#define singleton_m(name) \
static id _instance; \
+ (id)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; \
} \
\
- (oneway void)release \
{ \
\
} \
\
- (id)autorelease \
{ \
return _instance; \
} \
\
- (id)retain \
{ \
return _instance; \
} \
\
- (NSUInteger)retainCount \
{ \
return
1 ; \
} \
\
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _instance; \
}

#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值