ARC和MRC 兼容的单例模式

Posted 唐世光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC和MRC 兼容的单例模式相关的知识,希望对你有一定的参考价值。

一、ARC下的单例实现

  说明:在用户实例化的方法控制单次执行,同时开放单例的初始化方法。

技术分享
-(instancetype)init{

    self=[super init];
    if(self){
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
        });
    }
    return self;
    

}

static id instance; 
+(instancetype)allocWithZone:(struct _NSZone *)zone{ 
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{ 
    instance=[super allocWithZone:zone]; 
    }); 
return instance;
} 
 
 
+ (instancetype) shareAudio{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{ 
    instance=[[self alloc]init]; 
    }); 
    return instance; 
} 
 
+(id)copyWithZone:(struct _NSZone *)zone{ 
    return instance;
}
技术分享
二、MRC下的单例实现

   说明:在用户实例化的方法控制单次执行,同时开放单例的初始化方法,由于当前为MRC所以需要控制参内存管理的方法单次执行,因此相比ARC需要增加:

技术分享
static id instance; 
+(instancetype)allocWithZone:(struct _NSZone *)zone{ 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
        instance=[super allocWithZone:zone]; 
    }); 
    return instance; 
} 
 
 
+ (instancetype) shareAudio{
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
        instance=[[self alloc]init]; 
    }); 
    return instance; 
} 
-(oneway void)release{ 
} 
 
-(instancetype)autorelease{ 
    return instance; 
} 
 
-(instancetype)retain{ 
    return instance; 
} 
 
-(NSUInteger)retainCount{ 
    return 1; 
}
技术分享
三、兼容MRC 和ARC的宏定义

   说明:为了方便后期的引用,可以将单例抽取为宏定义,鉴于抽取的时候考虑到当前的手动计数和自动计数因此引入条件编译:

技术分享
#if !__has_feature(objc_arc)
======当前是ARC
#else
======当前是MRC
#endif

代码:
#define singleton_h(name)  + (instancetype) share##name;


#if !__has_feature(objc_arc)
#define singleton_m(name) static id instance;+(instancetype)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance=[super allocWithZone:zone];    });    return instance;}+ (instancetype) share##name{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance=[[self alloc]init];    });    return instance;}-(oneway void)release{}-(instancetype)autorelease{    return instance;}-(instancetype)retain{    return instance;}+(id)copyWithZone:(struct _NSZone *)zone{    return instance;}-(NSUInteger)retainCount{    return 1;}

#else

#define singleton_m(name)static id instance;+(instancetype)allocWithZone:(struct _NSZone *)zone{  static dispatch_once_t onceToken;  dispatch_once(&onceToken, ^{  instance=[super allocWithZone:zone];});  return instance;}+ (instancetype) share##name{  static dispatch_once_t onceToken;  dispatch_once(&onceToken, ^{   instance=[[self alloc]init];  });  return instance;}+(id)copyWithZone:(struct _NSZone *)zone{   return instance;}
#endif
技术分享
四、文件引用

1 在.h文件引用singleton_h(audio);

2 在.m文件引用singleton_m(audio);

以上是关于ARC和MRC 兼容的单例模式的主要内容,如果未能解决你的问题,请参考以下文章

iOS 中 ARC 项目 兼容 MRC

如何实现与 ARC 兼容的 Objective-C 单例?

0c-42-ARC模式下如何兼容非ARC的类

iOS开发ARC与MRC下单例的完整写法与通用宏定义

为啥苹果推荐使用 dispatch_once 来实现 ARC 下的单例模式?

iOS中的单例模式