IOS単例モードノート

2346 ワード

ここでは、単例モードの用途については説明しません.以下のコードは、主にあります.mファイルのコード.
#import "SingletonClass.h"

@implementation SingletonClass

+ (SingletonClass *)shareSingletonClass {
    SingletonClass* singleton = [[SingletonClass alloc] init];
    return singleton;
}

@end

ここでは、このメソッドを呼び出してグローバル一意インスタンスを得るクラスメソッドshareSingletonClassを定義しますが、グローバル一意インスタンスを生成する効果は明らかにありません.このメソッドを呼び出すたびに新しいインスタンスが生成されます.
再変更:
#import "SingletonClass.h"

static SingletonClass* singleton = nil;

@implementation SingletonClass

+ (SingletonClass *)shareSingletonClass {
    
    if (singleton == nil) {
        singleton = [[SingletonClass alloc] init];
    }
    
    return singleton;
}

@end

ここで静的SingletonClassインスタンスを生成し、このインスタンスが作成されていない場合は作成され、そうでない場合は直接このインスタンスに戻ると判断します.
しかし、この方法は単一スレッドにのみ適用され、マルチスレッドの場合、各スレッドは最初にsingleton=nilと判断し、複数のsingletonインスタンスが生成される.スレッドロックが必要です
+ (SingletonClass *)shareSingletonClass {
    
    @synchronized(self) {
        if (singleton == nil) {
            singleton = [[SingletonClass alloc] init];
        }
    }
    
    return singleton;
}

このようにしてもう一つの例が完成した.
しかし、高い同時スレッドがある場合、毎回if判断をしなければならないのは、性能が消費され、オンラインロックの中のコードは、少ないほど良いが、私たちが本当に必要としているのはsingleton=[[SingletonClass alloc]init];このコードは、スレッドロックをif判定に移すことができます.
+ (SingletonClass *)shareSingletonClass
{
    
    if (singleton == nil) {
        @synchronized(self) {
            singleton = [[SingletonClass alloc] init];
        }
    }
    
    return singleton;
}

しかし、このようにマルチスレッドでは、新しいスレッドがスレッドロックに近づき、新しいインスタンスが生成されるので、もう一度判断します.
+ (SingletonClass *)shareSingletonClass
{
    
    if (singleton == nil) {
        @synchronized(self) {
            if (singleton == nil) {
                singleton = [[SingletonClass alloc] init];
            }
        }
    }
    
    return singleton;
}

最初のif判定は、インスタンスが作成された後にのみスレッドロックに入ることができ、スレッドロック判定に入ることを減少させる.2つ目の判断は、マルチスレッドのときの判断で、ここまで入る確率はかなり少なくなっています.これは多層スレッドロックです.
実際、OBJCでは、単一の例について、方法を用意しています.
+ (SingletonClass *)shareSingletonClass
{
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[SingletonClass alloc] init];
    });
    
    return singleton;
}

システムの方法は,一般に最適化されるので,この方法を推奨する.