您的位置:首页 > 移动开发 > IOS开发

ios-单例模式饿汉式&GCD&懒汉式&宏方式的实现和条件编译

2017-08-22 20:34 507 查看
饿汉式其实就是当程序一启动就是创建单例,在ios中不推荐去使用

static id instance;
+ (void)load //装载内存时就实例化,仅此一次
{
_instance = [[self alloc] init];
}
+ (id)allocWithZone:(struct _NSZone *)zone
{
//这里可以不用加锁,因为是在load里面创建的
if (_instance == nil) { // 防止创建多次
_instance = [super allocWithZone:zone];
}
return _instance;
}
+ (instancetype)sharedManagerTool
{
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
GCD的单例实现方式

static id _instace;

+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
//这个函数是线程安全的
 dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}

+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}

- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
懒汉式的实现就是在用到的时候再去创建

static id _instance;
//alloc内部会调用这个代码
+ (id)allocWithZone:(struct _NSZone *)zone
{
if (_instance == nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance == nil) { // 防止创建多次
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}

+ (instancetype)sharedMusicTool
{
if (_instance == nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance == nil) { // 防止创建多次
_instance = [[self alloc] init];
}
}
}
return _instance;
}

- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
非ARC下的单例模式

static id _instace;

+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}

+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}

- (id)copyWithZone:(NSZone *)zone
{
return _instace;
}
//为了保证对象不被释放,所以在release中不做任何操作
-(oneway void)release
{
}
//retain的时候返回自己
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return 1;
}
//这里其实加不加都一样,因为最后会调用release操作,而我们又重写了release方法
- (id)autorelease {
    
    return self;
}
因为我们如果每用到一个类就要去复制这些代码,所以我们可以把这些代码定义成宏,确定就是不好调试。\这个的意思就是后面的一行都是它的.我们想用的话想把sharedInstance的Instance的名字改成我们自己传的名字,下面加()和传入参数name

// .h文件
#define SingletonH(name) + (instancetype)shared##name;

// .m文件
#define SingletonM(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:(NSZone *)zone \
{ \
return _instance; \
}

我们在写项目的时候如果想要指定在ARC下执行什么代码,在MRC下执行什么代码,我们可以用条件编译来写

#if __has_feature(objc_arc)
//编译环境是ARC
NSLog(@"kkk");
#else
//编译环境是MRC
NSLog(@"kkk");
#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐