一 概述
单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码,可以用宏判断是否为ARC环境
1 2 3 4 5
| #if __has_feature(objc_arc) //ARC #else //MRC #endif
|
二 几个概念
2.1 ARC和MRC
Objective-c中两种内存管理机制ARC、MRC
- ARC(Automatic Reference Counting):自动内存管理
- MRC(manual Reference Counting):手动内存管理
注意:Xcode4.1及其以前版本没有ARC,MRC与ARC的区别如下图。需要理解MRC,但实际使用时强推ARC
Objective-c语言中的MRC
在MRC的内存管理模式下,与对变量的管理相关的方法有:retain,release和autorelease。
retain和release方法操作的是引用计数,当引用计数为零时,便自动释放内存。并且可以用NSAutoreleasePoll对象,对加入自动释放池(autorelease调用)的变量进行管理,当drain时回收内存。
- retain:该方法的作用是将内存数据的所有权赋给另一个指针变量,引用数加1,即retainCout+=1;
- release:该方法是释放指针变量对内存数据的所有权,引用数减1,即retainCount-=1;
- autorelease:该方法是将该对象内存的管理放到autoreleasepool中
Objective-c语言中的ARC
在ARC中与内存管理有关的标识符,可以分为变量标识符和属性标识符,对于变量默认为__strong,而对于属性默认为unsafe_unretained。也存在autoreleasepool.
2.2 ##name代表什么意思
- ## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串
- 但它不可以是第一个或者最后一个子串
- 简单的说,“##”是一种分隔连接方式,它的作用是先分隔,然后进行强制连接
三 适配ARC和MRC代码(ILSingleton.h)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| // .h文件 #define ILSingletonH(name) + (instancetype)shared##name;
// .m文件 #if __has_feature(objc_arc)
#define ILSingletonM(name) \ static id _instace; \ \ + (id)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [super allocWithZone:zone]; \ }); \ return _instace; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [[self alloc] init]; \ }); \ return _instace; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instace; \ }
#else
#define ILSingletonM(name) \ static id _instace; \ \ + (id)allocWithZone:(struct _NSZone *)zone \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [super allocWithZone:zone]; \ }); \ return _instace; \ } \ \ + (instancetype)shared##name \ { \ static dispatch_once_t onceToken; \ dispatch_once(&onceToken, ^{ \ _instace = [[self alloc] init]; \ }); \ return _instace; \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return _instace; \ } \ \ - (oneway void)release { } \ - (id)retain { return self; } \ - (NSUInteger)retainCount { return 1;} \ - (id)autorelease { return self;}
#endif
|