Objective-Cのsingleton

「Objective‐Cフレーズブック」のSingletonの部分の記述が面白い。

p75より

Appleのドキュメントでは、シングルトンを作成する為に、+sharedInstanceメソッドの中で@synchronized(sefl)を使用する事を推奨しています。 そのアプローチは著しく遅く、このセクションで提案したアプローチよりも多くのコードが必要なため、あまりお勧めしません。

との事。

Appleのやり方、「シングルトンインスタンスの作成」 を見ると

static MyGizmoClass *sharedGizmoManager = nil;

+ (MyGizmoClass*)sharedManager
{
    @synchronized(self) {
        if (sharedGizmoManager == nil) {
            [[self alloc] init]; // ここでは代入していない
        }
    }
    return sharedGizmoManager;
}

+ (id)allocWithZone:(NSZone *)zone {
{
    @synchronized(self) {
        if (sharedGizmoManager == nil) {
            sharedGizmoManager = [super allocWithZone:zone];
            return sharedGizmoManager;  // 最初の割り当てで代入し、返す
        }
    }
    return nil; // 以降の割り当てではnilを返すようにする
}
.
.
.

となっており、確かに+ (MyGizmoClass*)sharedManagerで@synchronized(self)を使用している。

一方、「Objective‐Cフレーズブック」のやり方は、

static MyGizmoClass *sharedGizmoManager = nil;

+ (void) initialize
{
    if( [MyGizmoClass class] == self )
    {
        sharedGizmoManager = [self new];
    }
}

+ (MyGizmoClass*)sharedManager
{
    return sharedGizmoManager;
}

+ (id)allocWithZone:(NSZone *)zone {
{
    if( sharedGizmoManager && [MyGizmoClass class] == self )
    {
        [NSException raise:NSGenericException
                    format:@"May not create more than one instance of singleton."];
    }

    return [super allocWithZone:zone];
}
.
.
.

となっており、@synchronizedがなく、全体的にすっきりしたコードだ。

しかし、脚注にGCCのランタイムにはバグがあって「Objective‐Cフレーズブック」のやり方は動作しないような事が書いてある。

結論としては、gccを使う場合はAppleの推奨する方法を使うのが良いとの事だろうか。