单例在ARC和MRC中
创建一个单例对象,需要做以下几点:
1.定义一个全局的static类变量instance,赋值为nil
2.重写allocWithZone方法:内部用dispatch_once来保证线程安全
3.在MRC中,重写release方法
4.重写retain方法:直接返回instance
5.重写copyWithZone和mutableCopyWithZone方法
注意:
alloc方法中默认调用allocWithZone,所以重写的时候,重写allocWithZone即可
内存中只有一份,因此可以定义为static,静态变量在内存中只有一份
在ARC和MRC中,重写方法有所不同,MRC需要对retain,copy等操作进行重写,而ARC不需要.
我们可以动态判断,统一写一个单例xx.h的宏.
定义宏的原因:
1.如果有多个单例对象,那么创建时都需要重新写,可以考虑简化目的.
2.如果以父类的形式定义一个单例父类,那么集成于谁?NSObject?UIView?
创建一个singleTon.h文件
#ifndef __ARC_MRC_singleTon_h
#define __ARC_MRC_singleTon_h
//头部分
#define singleTon_H(name) + (instancetype) share##name
//实现部分
//判断是否是ARC
//ARC
#if __has_feature(objc_arc)
#define singleTon_M(name) \
+ (instancetype)share##name { \
return [[self alloc] init]; \
} \
\
static id instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
if (instance == nil) { \
instance = [super allocWithZone:zone]; \
} \
}); \
return instance; \
} \
\
- (id)copyWithZone:(struct _NSZone *)zone { \
return instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone { \
return instance; \
}
#else //MRC
#define singleTon_M(name) \
+ (instancetype)share##name { \
return [[self alloc] init]; \
} \
\
static id instance = nil; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
if (instance == nil) { \
instance = [super allocWithZone:zone]; \
} \
}); \
return instance; \
} \
\
- (oneway void)release { \
} \
- (instancetype)retain { \
return instance; \
} \
\
- (id)copyWithZone:(struct _NSZone *)zone { \
return instance; \
} \
- (id)mutableCopyWithZone:(NSZone *)zone { \
return instance; \
}
#endif
#endif
创建一个Animal的单例对象:
Animal.h
#import <Foundation/Foundation.h>
#import "singleTon.h"
@interface Animal : NSObject
singleTon_H(Animal);
@end
Animal.m
#import "Animal.h"
#import "singleTon.h"
@interface Animal () <NSCopying,NSMutableCopying>
@end
@implementation Animal
singleTon_M(Animal);
@end
调用方法:
程序为MRC中的测试情况,ARC中不需要release操作了.
#import <Foundation/Foundation.h>
#import "Animal.h"
int main(int argc, const char * argv[]) {
Animal *tool1 = [[Animal alloc] init];
[tool1 release];
NSLog(@"tool1 %zd",tool1.retainCount);
Animal *tool2 = [[Animal alloc] init];
Animal *tool3 = [Animal shareAnimal];
Animal *tool4 = [tool3 retain];
Animal *tool5 = [tool3 copy];
NSLog(@"tool4 %zd",tool4.retainCount);
NSLog(@"tool5 %zd",tool5.retainCount);
NSLog(@"%p %p %p",tool1,tool2,tool3);
return 0;
}
结果如下:2015-07-01 13:42:34.591 单例ARC-MRC[1098:207060] tool1 1
2015-07-01 13:42:34.592 单例ARC-MRC[1098:207060] tool4 1
2015-07-01 13:42:34.593 单例ARC-MRC[1098:207060] tool5 1
2015-07-01 13:42:34.593 单例ARC-MRC[1098:207060] 0x100112000 0x100112000 0x100112000