单例
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
#import "Person.h"
static Person *_instance;
@implementation Person
//可以在load方法中创建一个自己类的对象
+ (void)load
{
_instance = [[Person alloc]init];
}
//在外部调用这个方法拿到单例
+ (instancetype)sharedPerson{
return _instance;
}
//防止再创建新的对象,如果创建,抛出异常
+ (instancetype)alloc
{
if(_instance)
{
NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason:@"只能创建一个实例,无法创建第二个" userInfo:nil];
[exception raise];
}
return [super alloc];
}
@end
在考虑多线程以及ARC机制情况下的高级单例写法
#import "Person.h"
@implementation Person
static Person *_instance;
//相比重写alloc,重写allocWithZone更换,因为在执行alloc时会执行allocWithZone
//+ (instancetype)alloc
//{
//
//}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
//要考虑多线程访问安全问题
//方法1:加互斥锁
// @synchronized (self) {
// if(_instance == nil)
// {
// _instance = [super allocWithZone:zone];
// }
// }
//方法2:GCD一次性函数,本身就是线程安全的
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//可以创建一个类方法
+ (instancetype)sharePerson
{
return [[self alloc]init];
}
//做的更完善一点,可以重写2个copy方法,但是本类要先遵守<NSCopying,NSMutableCopying>协议
- (id)copy
{
return _instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
@end
非ARC(MRC)机制情况下的高级单例写法,仅了解即可
//除了以上ARC内的写法,还要重写以下函数
- (oneway void)release
{
//置空
}
- (instancetype)retain
{
return _instance;
}
- (NSUInteger)retainCount
{
return MAXFLOAT;
}
单例的宏
#define SingleModeH(name) +(instancetype)share##name;
#if __has_feature(objc_arc)
//条件满足 ARC
#define SingleModeM(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\
{\
return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}
#else
//MRC
#define SingleModeM(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\
{\
return [[self alloc]init];\
}\
\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(oneway void)release\
{\
}\
\
-(instancetype)retain\
{\
return _instance;\
}\
\
-(NSUInteger)retainCount\
{\
return MAXFLOAT;\
}
#endif
如果某个类想用这个宏做单例模式
h文件
#import <Foundation/Foundation.h>
#import "SingleMode.h"
@interface Person : NSObject
SingleModeH(Person);
@end
m文件
#import "Person.h"
@implementation Person
static Person *_instance;
SingleModeM(Person);
@end
这样就快速实现了单例模式
下面试试看,这样做是不是实现了单例:
Person *p1 = [[Person alloc]init];
NSLog(@"%p",p1);
Person *p2 = [[Person alloc]init];
NSLog(@"%p",p2);
Person *p3 = [Person new];
NSLog(@"%p",p3);
Person *p4 = [Person sharePerson];
NSLog(@"%p",p4);
Person *p5 = [p1 copy];
NSLog(@"%p",p5);
Person *p6 = [p1 mutableCopy];
NSLog(@"%p",p6);