편집 :이 구현은 ARC에서 더 이상 사용되지 않습니다. ARC와 호환되는 Objective-C 싱글 톤을 어떻게 구현합니까?를 살펴보십시오 . 올바른 구현을 위해.
다른 답변에서 읽은 초기화의 모든 구현은 일반적인 오류를 공유합니다.
+ (void) initialize {
_instance = [[MySingletonClass alloc] init] // <----- Wrong!
}
+ (void) initialize {
if (self == [MySingletonClass class]){ // <----- Correct!
_instance = [[MySingletonClass alloc] init]
}
}
Apple 설명서는 초기화 블록에서 클래스 유형을 확인하도록 권장합니다. 서브 클래스는 기본적으로 initialize를 호출하기 때문입니다. KVO를 통해 서브 클래스를 간접적으로 생성 할 수있는 명백한 경우가 있습니다. 다른 클래스에 다음 줄을 추가하는 경우 :
[[MySingletonClass getInstance] addObserver:self forKeyPath:@"foo" options:0 context:nil]
Objective-C는 내재적으로 MySingletonClass의 서브 클래스를 작성하여 두 번째 트리거를 발생 +initialize
시킵니다.
다음과 같이 init 블록에서 중복 초기화를 암시 적으로 확인해야한다고 생각할 수 있습니다.
- (id) init { <----- Wrong!
if (_instance != nil) {
// Some hack
}
else {
// Do stuff
}
return self;
}
그러나 당신은 발에 자신을 쏠 것입니다; 또는 다른 개발자에게 발을 쏠 기회를 줄 수도 있습니다.
- (id) init { <----- Correct!
NSAssert(_instance == nil, @"Duplication initialization of singleton");
self = [super init];
if (self){
// Do stuff
}
return self;
}
TL; DR, 여기 내 구현입니다
@implementation MySingletonClass
static MySingletonClass * _instance;
+ (void) initialize {
if (self == [MySingletonClass class]){
_instance = [[MySingletonClass alloc] init];
}
}
- (id) init {
ZAssert (_instance == nil, @"Duplication initialization of singleton");
self = [super init];
if (self) {
// Initialization
}
return self;
}
+ (id) getInstance {
return _instance;
}
@end
ZAssert를 자체 어설 션 매크로 또는 NSAssert로 바꿉니다.