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

单例模式的作用:

1,能够保证在程序执行过程。一个类仅仅有一个实例,并且该实例易于供外界訪问

2,从而方便地控制了实例个数,并节约系统资源

单例模式的使用场合:

在整个应用程序中,共享一份资源(这份资源仅仅须要创建初始化1次)

单例模式在ARC\MRC环境下的写法有所不同。须要编写2套不同的代码

能够用宏推断是否为ARC环境

#if __has_feature(objc_arc)

//ARC

#else

//MRC

#endif

在游戏中,音乐在不同的场景可能同样,我们应该仅仅要创建一份,这时候我们就应该使用单例模式。能够节省内存;

在ARC环境下,实现单例模式:  
代码例如以下:

要使得他们alloc init一份,就能够使用GCD的dispatch_once,还能够保证线程安全。

#import "HMAudioTool.h"

@interface HPAudioTool()

@end

@implementation HPAudioTool

//// 定义一份变量(整个程序执行过程中,
仅仅有1份)

static id _instance;

- (id)init

{

if (self = [super init]) {

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 = [super allocWithZone:zone];

});

//
返回对象

return _instance;

}

+ (instancetype)sharedAudioTool

{

//
里面的代码永远仅仅运行1次

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instance = [[self alloc] init];

});

//
返回对象

return _instance;

}

+ (id)copyWithZone:(struct _NSZone *)zone

{

return _instance;

}

@end

那么在MRC中呢?那当然就要考虑内存的释放了;必需要release了。

然而在release方法中,会调用[super release];

还有autorelease,retain,retainCount,copyWithZone;都得保证调用一次。

代码例如以下:

@interface HPAudioTool()

@end

@implementation HPAudioTool

//// 定义一份变量(整个程序执行过程中,
仅仅有1份)

static id _instance;

- (id)init

{

if (self = [super init]) {

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 = [super allocWithZone:zone];

});

//
返回对象

return _instance;

}

+ (instancetype)sharedAudioTool

{

//
里面的代码永远仅仅运行1次

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instance = [[self alloc] init];

});

//
返回对象

return _instance;

}

+ (id)copyWithZone:(struct _NSZone *)zone

{

return _instance;

}

- (oneway void)release

{

}

- (id)autorelease

{

return _instance;

}

- (id)retain

{

return _instance;

}

- (NSUInteger)retainCount

{

return 1;

}

+ (id)copyWithZone:(struct _NSZone *)zone

{

return _instance;

}

@end

当然我们在使用过程中。我们能够把这些代码写成宏,使用起来方便,便于改动。

为了兼容ARC和MRC,我们能够将代码合并例如以下:

// ## :
连接字符串和參数

#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

然后大家直接能够拷贝走,直接拿去调用。


单例模式 - GCD 、兼容ARC和MRC的更多相关文章

  1. 完美单例宏定义(兼容ARC和MRC),项目中可以直接使用

     单例模式: 1.永远只分配一块内存来创建对象 2.提供一个类方法, 返回内部唯一的一个对象(一个实例) 3.最好保证init方法也只初始化一次 写一个宏定义文件,传入宏定义函数名,自动生成符合类名的 ...

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

    #import "XMGTool.h" /** * 1:ARC下的完整的单例写法:alloc内部会调用+(instancetype)allocWithZone:(struct _N ...

  3. ARC以及MRC中setter方法

    ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下A ...

  4. ARC 和 MRC 小结

    ARC 和 MRC 内存管理 从 MRC—>ARC 就是将内存管理部分,从开发者的函数中转移到函数外部的runtime 中.由于 runtime 的开发简单,逻辑层次高,所以 runtime 的 ...

  5. ARC、MRC混编

    Xcode5之后,新建iOS工程,默认都是ARC模式,但是有时候我们的项目中需要用到一些第三方框架,我们下载下来却发现是非ARC的,这时候我们需要进行ARC和MRC混编. 第一种方式: Edit-&g ...

  6. iOS内存管理 ARC与MRC

    想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC ...

  7. DES加密(支持ARC与MRC)

    DES加密(支持ARC与MRC) 源文件: YXCrypto.h 与 YXCrypto.m // // YXCrypto.h // 用秘钥给字符串加密或者解密 // // Created by You ...

  8. ARC以及MRC中setter方法的差异

    ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下A ...

  9. ARC和MRC 兼容的单例模式

    一.ARC下的单例实现 说明:在用户实例化的方法控制单次执行,同时开放单例的初始化方法. -(instancetype)init{ self=[super init]; if(self){ stati ...

随机推荐

  1. [ CodeVS冲杯之路 ] P3038

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/3038/ 按照题目给定的方法,一步步推下去,直到推到1就输出次数 至于-1的话,一开始想直接用数组判重,但是怕T掉,于是 ...

  2. [转]Google 的开源技术protobuf 简介与例子

    本文来自CSDN博客:http://blog.csdn.NET/program_think/archive/2009/05/31/4229773.aspx 今天来介绍一下“Protocol Buffe ...

  3. zabbix 硬盘状态收集,制作表格

    将zabbix首页复制到a文件里,这里主要是用到首页里 最近出现的问题 的信息 # -*- coding:utf-8 -*- import time import os from openpyxl i ...

  4. 第一章:1-10、试在下列条件下比较电路交换和分组交换。要传送的报文共x(bit),从源站到目的站共经过k段链路,每段链路的传播时延为d(s),数据率为C(bit/s)。在电路交换时电路的建立时间为s(s)。在分组交换时分组长度为p(bit),且各结点的排队等待时间可忽略不计。问在怎样的条件下,分组交换的时延比电路交换的要小?

    <计算机网络>谢希仁著第四版课后习题答案答:对电路交换,当t=s时,链路建立: 当t=s+x/C,发送完最后一bit:                 当t=s+x/C+kd,所有的信息到 ...

  5. AC日记——Little Elephant and Numbers codeforces 221b

    221B - Little Elephant and Numbers 思路: 水题: 代码: #include <cmath> #include <cstdio> #inclu ...

  6. Python与数据库[1] -> 数据库接口/DB-API[3] -> ODBC 适配器

    ODBC适配器 / ODBC Adaptor ODBC(Open Database Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows Open Service ...

  7. 818E - Card Game Again(尺取法)

    818E - Card Game Again 题意 给出一个数列,选择连续的一段使得这些数字的乘积是 k 的倍数,问合法的方案数. 分析 尺取法.设 num 为连续的数的乘积,只要对于 k 的每个素因 ...

  8. linux中,在在shadowsoks下怎么更新软件

    在shadowsoks下怎么更新软件 先描述一下我的情况.我们学校不给大一开通校园网,我自己租用了***的vps服务器,搭建shadowsocks,(使用ipv6地址才能连接),开始了自己悲催的上网生 ...

  9. luogu P1347 排序

    题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D.在这道题中,我们将给你一系列形如A<B ...

  10. 弹出视图/弹出模态presentViewController与presentModalViewController

    一.主要用途 弹出模态ViewController是IOS变成中很有用的一个技术,UIKit提供的一些专门用于模态显示的ViewController,如UIImagePickerController等 ...