Objective-C でシングルトンパターンのクラスを作成するメモです。
シングルトンパターンとは、クラスのインスタンスがひとつしか生成されないことを保証するデザインパターンです。NSUserDefaults などがシングルトンなクラスです。

シングルトンなクラスを作成するときのポイントです。

  1. 静的インスタンスを生成して、ひとつだけ作成したインスタンスを入れておく
  2. アップルが推奨しているクラスファクトリーメソッド名(sharedInstance や sharedManager) を使用して、インスタンス未生成時のみインスタンスを生成する
  3. インスタンスがひとつしか生成されないことを保証するために [[Hoge alloc] init] とされた場合の対策をしておく
  4. retain, retainCount, copyWithZone, release, autorelease をオーバライドしてシングルトン状態が保持されるようにする

で、作成したのが以下のようなコードです。これに必要なメソッドなどを適宜追加して使います。インスタンスを生成する処理を @synchronized(){} で囲うことにより同時に複数のスレッドから実行されたときにも、処理が同時に実行されないようにブロックされ、シングルトン状態を保持できます。

#import "History.h"

@implementation History

static History* sharedHistory = nil;

+ (History*)sharedManager {
	@synchronized(self) {
		if (sharedHistory == nil) {
			sharedHistory = [[self alloc] init];
		}
	}
	return sharedHistory;
}

+ (id)allocWithZone:(NSZone *)zone {
	@synchronized(self) {
		if (sharedHistory == nil) {
			sharedHistory = [super allocWithZone:zone];
			return sharedHistory;
		}
	}
	return nil;
}

- (id)copyWithZone:(NSZone*)zone {
	return self;  // シングルトン状態を保持するため何もせず self を返す
}

- (id)retain {
	return self;  // シングルトン状態を保持するため何もせず self を返す
}

- (unsigned)retainCount {
	return UINT_MAX;  // 解放できないインスタンスを表すため unsigned int 値の最大値 UINT_MAX を返す
}

- (void)release {
	// シングルトン状態を保持するため何もしない
}

- (id)autorelease {
	return self;  // シングルトン状態を保持するため何もせず self を返す
}

@end

実際にインスタンスを取得する際は以下のようになります。

History* history = [History sharedManager];

参考サイト
Cocoa Fundamentals Guide: シングルトンインスタンスの作成

先月も今月もほとんどブログを更新していないかった。反省して更新するようにしたいです。

関連する投稿