单例模式的实现(ARC与非ARC)
来源:互联网 发布:淘宝联盟推广位爱分享 编辑:程序博客网 时间:2024/05/17 07:02
单例模式是一种很重要的设计模式,在iOS开发中,通过使用单例设计模式来实现在程序生命周期内只有一个实例存在来节省内存开销。
下面是ARC中单例模式的实现代码:
在自定义的类.m文件中,需要实现下列的方法
#import"HMAudioTool.h"
@interfaceHMAudioTool()
@end
@implementationHMAudioTool
////定义一份变量(整个程序运行过程中,只有1份)
staticid _instance;
- (id)init
{
if (self= [superinit]) {
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 = [superallocWithZone:zone];
});
// 返回对象
return _instance;
}
+ (instancetype)sharedAudioTool
{
// 里面的代码永远只执行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[selfalloc]init];
});
// 返回对象
return _instance;
}
@interfaceHMAudioTool()
@end
@implementationHMAudioTool
////定义一份变量(整个程序运行过程中,只有1份)
staticid _instance;
- (id)init
{
if (self= [superinit]) {
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 = [superallocWithZone:zone];
});
// 返回对象
return _instance;
}
+ (instancetype)sharedAudioTool
{
// 里面的代码永远只执行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[selfalloc]init];
});
// 返回对象
return _instance;
}
@end
通过重写allocWithZone,copyWithZone,以及init方法来实现在内存中只存在一个HMAudioTool对象.
上面的代码是ARC下单例的实现,而对于非ARC而言,还需要重写release,autorelease,retain,retainCount来保证返回的对象为单例,代码如下:
+ (id)copyWithZone:(struct_NSZone*)zone
{
return _instance;
}
- (onewayvoid)release
{
}
- (instancetype)autorelease
{
return _instance;
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
return 1;
{
return _instance;
}
- (onewayvoid)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
- 单例模式的实现(ARC与非ARC)
- oc非ARC机制实现单例模式
- IOS-混合使用ARC与非ARC模式的代码
- 在ARC与非ARC下 iOS创建单例 遇到的问题
- iOS开发单例模式Non-ARC(非ARC)和ARC+GCD
- arc 与非arc
- ARC与非ARC
- ARC 和非 ARC 的混合模式
- ARC 和非 ARC 的混合模式
- 原创-ARC与非ARC的区别
- ARC与非ARC的循环引用
- ARC模式下的单例写法。
- ARC下的单例模式
- iOS的ARC/MRC单例模式
- ARC和非ARC模式
- 非ARC情况下---用GCD实现单例模式
- 【iOS开发系列】单例模式宏(兼容ARC和非ARC)
- XCode工程中ARC模式与非ARC模式共用
- QT放单刷单最安全公会|QT放单刷单最安全平台|QT放单刷单最安全频道| 24团珍帅推荐qt1130平台
- 通信系统为何编码和解码(第三次作业)
- 对canvas的translate()方法的理解
- 自己出的题 squee_spoon and his Cube III
- .net中对象占用资源的回收
- 单例模式的实现(ARC与非ARC)
- Eclipse提交代码错误:rejected –non-fast-forward
- php设计模式入门-观察者模式
- Android ActionBar应用实战,高仿微信主界面的设计
- STM32在MDK5下建立工程文件步骤分析
- 简单工厂模式(二)
- 列选取原则
- Please login to the following domain:This is We Cloud Technology Group,please enter your passcode
- T001-UT001-0018