Objective-C というか Cocoa でのシングルトンの作法のメモ。
ARC 対応版 / GCD 利用
- 参照ドキュメント
- TheElements サンプル Version 1.12, 2013-04-11
以下、上記サンプルの PeriodicElements.m からの抜粋。
// we use the singleton approach, one collection for the entire application
static PeriodicElements *sharedPeriodicElementsInstance = nil;
+ (PeriodicElements *)sharedPeriodicElements {
@synchronized(self) {
static dispatch_once_t pred;
dispatch_once(&pred, ^{ sharedPeriodicElementsInstance = [[self alloc] init]; });
}
return sharedPeriodicElementsInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedPeriodicElementsInstance == nil) {
sharedPeriodicElementsInstance = [super allocWithZone:zone];
return sharedPeriodicElementsInstance; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
ARC 非対応版
- 参照ドキュメント
- Cocoa Fundamentals Guide 2010-12-13
- Cocoa Objects
- Creating a Singleton Instance
以下、上記 “Creating a Singleton Instance” の “Listing 2-15 Strict implementation of a singleton” の抜粋。
static MyGizmoClass *sharedGizmoManager = nil;
+ (MyGizmoClass*)sharedManager
{
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
return sharedGizmoManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
シングルトンのみでなく通常のオブジェクトも作成したい場合には、allocWithZone:
をオーバーライドしない。