使用GCD实现单例,可以保证线程安全
//只要实现了下面copy方法,该<NSCopying>可以不用写
@interface JKYPerson () <NSCopying>
@end
static JKYPerson *_person;
@implemention JKYPerson
- (instancetype)allocWithZone:(NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
+(instancetype)shardPerson {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc] init];
});
return _person;
}
// 为了严谨起见,应该为单例实现copy方法,只需返回_person即可
- (id)copyWithCZone:(NSZone *)zone
{
return _person;
}
@end
如果程序中使用单例比较多,则可以将上面但是得声明与实现定义到宏里。如下:
```objc
// JKYSingleton.h
// ##号是宏连接符
#define JKYSingletonH(name) +(instanceType)share##name;
#define JKYSingletonM(name) \
static JKYPerson *_instance; \
+ (instancetype)allocWithZone:(NSZone *)zone { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
+(instancetype)shard##name { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
- (id)copyWithCZone:(NSZone *)zone \
{ \
return _instance; \
}
//
// JKYPerson.h
#import "JKYSingleton.h"
@interface JKYPerson : NSObject
JKYSingletonH(Person)
@end
// JKYPerson.m
@implemention JKYPerson
JKYSingletonM(Person)
@end
注:
- 如果不是用GCD创建单例,而是自己写单例,则必须使用
@synchronized(锁对象){...}
加锁 - 不同的类不能继承同一个单例类