Objective-C在ARC下结合GCD的单例模式和宏模版
2024-09-08 06:10:58
单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法:
static MyGizmoClass *sharedGizmoManager = nil; + (MyGizmoClass*)sharedManager
{
@synchronized(self) {
if (sharedGizmoManager == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedGizmoManager;
} + (id)allocWithZone:(NSZone *)zone
{
@synchronized(self) {
if (sharedGizmoManager == nil) {
sharedGizmoManager = [super allocWithZone:zone];
return sharedGizmoManager; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
} - (id)copyWithZone:(NSZone *)zone
{
return self;
} - (id)retain
{
return self;
} - (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
} - (void)release
{
//do nothing
} - (id)autorelease
{
return self;
}
现在iOS5之后普遍使用了ARC技术,原来这个写法就显得很累赘了,release已经不使用了。
咱们可以结合GCD来实现单例模式:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
使用dispatch_once,这个方法的意思是在应用程序生命周期内,这方法只执行一次,这就是ARC下结合GCD的一个单例的代码
因为我们可能需要多个单例的类,每个都写一次比较麻烦,可以更方便一些,把这些代码写成宏的形式,只需要传入类名就可以创建一个单例的类了。
通过传入类名创建头文件中单例方法的名称:
#define DEFINE_SINGLETON_FOR_HEADER(className) \
\
+ (className *)shared##className;
通过传入类名创建单例方法的实现
#define DEFINE_SINGLETON_FOR_CLASS(className) \
\
+ (className *)shared##className { \
static className *shared##className = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
shared##className = [[self alloc] init]; \
}); \
return shared##className; \
}
使用宏:
在项目中新建了一个类testSingleton,并且有.h 和.m文件。
.h
.m中的代码:
#import "testSingleton.h" @implementation testSingleton
DEFINE_SINGLETON_FOR_CLASS(testSingleton)
@end
#define DEFINE_SINGLETON_FOR_HEADER(className) \
\
+ (className *)shared##className; #define DEFINE_SINGLETON_FOR_CLASS(className) \
\
+ (className *)shared##className { \
static className *shared##className = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
shared##className = [[self alloc] init]; \
}); \
return shared##className; \
} #import <Foundation/Foundation.h> @interface testSingleton : NSObject
DEFINE_SINGLETON_FOR_HEADER(testSingleton);
@end
你可以把宏单独放到项目管理宏的文件中。这里是为了方便演示放到和testSingleton.h文件了。
获取单例:
- (void)test
{
testSingleton *testShare = [testSingleton sharedtestSingleton];
}
最新文章
- protocol
- [学习笔记] 七步从AngularJS菜鸟到专家(7):Routing [转]
- SpringMVC 接收复杂对象
- db4o种纯对象数据库引擎
- Java中throws和throw的区别讲解
- hadoop 2.0 详细配置教程
- 转型函数 Boolean()
- HTTP学习笔记4-请求与响应结构例子
- NAMESPACE
- 项目总结SpringMVC+hibernate框架 web.xml 分析(2)
- Lustre文件系统测试——obdfilter-survey测试
- MYSQL 表大小限制
- linux6下源码安装mysql5.6
- hdu1873 看病要排队【优先队列】
- android 开发 RecyclerView 横排列列表布局
- sql 跨服务器查询数据
- JavaScript的格式--从格式做起,做最严谨的工程师
- js插件---在线类似excel生成图表插件解决方案
- java bulid path 和 WEB-INF/lib 下jar 包区别
- js 给json添加新的字段,或者添加一组数据,在JS数组指定位置删除、插入、替换元素
热门文章
- Ubuntu 16.04安装Gufw防火墙(转)
- pojo类对应的就是数据库中的表,pojo类属性类型一定要用包装类Integer等
- eclipse编译项目用maven编译问题
- MySQL: 打开binlog选项后无法重启MySQL
- 【CV知识学习】【转】beyond Bags of features for rec scenen categories。基于词袋模型改进的自然场景识别方法
- 正确移除List中对象
- LeetCode 172. Factorial Trailing Zeroes (阶乘末尾零的数量)
- JSP-Runoob:JSP 服务器响应
- JVM-垃圾回收器
- Vue.js经典开源项目汇总-前端参考资源