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);

时间: 2024-10-08 11:13:08

ARC和MRC 兼容的单例模式的相关文章

单例模式 - GCD 、兼容ARC和MRC

单例模式 - GCD .兼容ARC和MRC 单例模式的作用: 1,可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问 2,从而方便地控制了实例个数,并节约系统资源 单例模式的使用场合: 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次) 单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码 可以用宏判断是否为ARC环境 #if __has_feature(objc_arc) //ARC #else //MRC #endif 在游戏中,音乐在不同的场景

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

#import "XMGTool.h" /** * 1:ARC下的完整的单例写法:alloc内部会调用+(instancetype)allocWithZone:(struct _NSZone *)zone方法,所以重写该方法,用GCD一次性函数,默认是线程安全的加了一把锁,也可以自己去加锁 @synchronized(self) { if (_instance == nil) { _instance = [super allocWithZone:zone]; } } 2:还要考虑cop

iOS arc VS mrc学习笔记

一.* Core Foundation与objective-c Object进行交换 * 对于Core Foundation与objective-cObject进行交换时,需要用到的ARC管理机制有: (1) (__bridge_transfer) op or alternatively CFBridgingRelease(op) is used to consume a retain-count of a CFTypeRef while transferring it over to ARC.

iOS内存管理 ARC与MRC

想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC).OC的内存管理机制叫做引用计数,就是一块内存地址可以同时被多个对象引用,每引用一次,引用计数都会递增1,当对象每解除一次引用,引用计数就会递减1,直到引用计数为0时,系统才会讲这块内存地址回收释放掉,这与C/C++语言有些不同,但是它们都遵守同一个内存管理法则:谁申请,谁释放. 在早些时候,iO

ARC以及MRC中setter方法

ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下ARC下的setter方法: 小结: 1. 一旦你重写了getter.setter方法,你必须使用@synthesize variable = _variable来区分属性名与方法名. 2. ARC与MRC的getter方法一致,就setter方法有着略微区别.

Block在内存中的位置在arc和mrc的区别

关于block在内存中的位置, http://tanqisen.github.io/blog/2013/04/19/gcd-block-cycle-retain/这篇文章解释的不错,但是好像并没有区分arc和mrc的区别 block的位置分为这几种 NSGlobalBlock:类似函数,位于text段: NSStackBlock:位于栈内存,函数返回后Block将无效: NSMallocBlock:位于堆内存. 不引用外部环境变量的block都属于NSGlobalBlock, NSStackBl

@autoreleasepool在ARC和MRC下的区别

MRC这个词应该是我编的,ARC,Automatic Reference Counting,手工引用计数就应该是:Manual Reference Counting,那就应该是MRC喽,不过没有见人这样用过. ARC引入了新的语句管理自动释放池语法: @autoreleasepool {     // Code, such as a loop that creates a large number of temporary objects.} 测试了一下,在ARC情况下和MRC情况下对象的释放有

ios-实现ARC与MRC混编

选择target -> build phases -> compile sources -> 用ARC的文件将compiler flags设置为:-fobjc-arc,用MRC的文件将compiler flags设置为:-fno-objc-arc. 同样,如果一个项目用ARC,而某个文件需要用MRC,只需要在compiler sources中将该文件的 compiler flags设置为-fno-objc-arc即可. ios-实现ARC与MRC混编

ARC以及MRC中setter方法的差异

ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下ARC下的setter方法: 小结: 1. 一旦你重写了getter.setter方法,你必须使用@synthesize variable = _variable来区分属性名与方法名. 2. ARC与MRC的getter方法一致,就setter方法有着略微区别. ARC以及MRC中setter方法的差