单例模式 - GCD 、兼容ARC和MRC
单例模式 - 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的更多相关文章
- 完美单例宏定义(兼容ARC和MRC),项目中可以直接使用
单例模式: 1.永远只分配一块内存来创建对象 2.提供一个类方法, 返回内部唯一的一个对象(一个实例) 3.最好保证init方法也只初始化一次 写一个宏定义文件,传入宏定义函数名,自动生成符合类名的 ...
- iOS开发ARC与MRC下单例的完整写法与通用宏定义
#import "XMGTool.h" /** * 1:ARC下的完整的单例写法:alloc内部会调用+(instancetype)allocWithZone:(struct _N ...
- ARC以及MRC中setter方法
ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下A ...
- ARC 和 MRC 小结
ARC 和 MRC 内存管理 从 MRC—>ARC 就是将内存管理部分,从开发者的函数中转移到函数外部的runtime 中.由于 runtime 的开发简单,逻辑层次高,所以 runtime 的 ...
- ARC、MRC混编
Xcode5之后,新建iOS工程,默认都是ARC模式,但是有时候我们的项目中需要用到一些第三方框架,我们下载下来却发现是非ARC的,这时候我们需要进行ARC和MRC混编. 第一种方式: Edit-&g ...
- iOS内存管理 ARC与MRC
想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC ...
- DES加密(支持ARC与MRC)
DES加密(支持ARC与MRC) 源文件: YXCrypto.h 与 YXCrypto.m // // YXCrypto.h // 用秘钥给字符串加密或者解密 // // Created by You ...
- ARC以及MRC中setter方法的差异
ARC以及MRC中setter方法的差异 有时候,你会需要重写setter或者getter方法,你知道么,ARC与MRC的setter方法是有着差异的呢. 先看下MRC下的setter方法: 在看下A ...
- ARC和MRC 兼容的单例模式
一.ARC下的单例实现 说明:在用户实例化的方法控制单次执行,同时开放单例的初始化方法. -(instancetype)init{ self=[super init]; if(self){ stati ...
随机推荐
- BeeUISignal详解
https://github.com/i5ting/Bee_Tutorial/wiki/BeeUISignal%E8%AF%A6%E8%A7%A3 BeeUISignal是beeframework的核 ...
- 关闭 C4996 警告(_CRT_SECURE_NO_DEPRECATE)
在使用VC 2005 的开发者会遇到这样的问题,在使用std命名空间库函数的时候,往往会出现类似于下面的警告: warning C4996: strcpy was declared deprecate ...
- 原生JavaScript实现jQuery的hasClass,removeClass,addClass,toggleClass
介绍: 1.hasClass:判断DOM元素是否存在类. 2.addClass:为的DOM元素添加类. 3.removeClass:删除DOM元素的类. 4.toggleClass:如果DOM元素存在 ...
- python的位运算
# &: 都是1,才为1,否则为零 # |: 都是0,才为0,否则为1 # ^: 相同为0,相异为1 a = bin(20) b = bin(16) print(a) # 0b10100 pr ...
- Python的支持工具[0] -> 环境包管理工具[0] -> pip
pip包管理工具 / pip Package Management Tools pip是一个Python包管理工具,主要是用于安装PyPI上的软件包,可以替代easy_install工具. 1 pip ...
- Codeforces 246E - Blood Cousins Return (树上启发式合并)
246E - Blood Cousins Return 题意 给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor,每个节点有名字,名字不唯一.多次查询,给出 u k ...
- 差分【p3948】 数据结构
顾z 你没有发现两个字里的blog都不一样嘛 qwq 题目描述-->p3948 数据结构 分析 其实这题完全没有分析的 qwq. 只是因为写了差分数组相关知识,所以顺便写一下题解 qwq. 对于 ...
- Linq GroupJoin , Join
static void Main(string[] args) { List<Person> persons = new List<Person> { }, }, }; Lis ...
- python查询mangodb
from bson.objectid import ObjectId import pymongo #查询代码 #连接本机mongodb conn=pymongo.Connection() #指定 ...
- 韩国研发AI武器遭抵制,武器自带“头脑”将多可怕
禁止自主武器的开发,事实上并不妨碍人工智能技术的发展,也不妨碍其被正常用于军事领域,其中的关键就在于,人类是否拥有控制权,能否在关键时刻对其进行关闭. 文 |郑伟彬 转自新京报专栏 4月4日,全球超过 ...