ARC のシングルトンの共有インスタンス アクセサーで dispatch_once を使用する正確な理由は何ですか?
+ (MyClass *)sharedInstance
{
// Static local predicate must be initialized to 0
static MyClass *sharedInstance = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
sharedInstance = [[MyClass alloc] init];
// Do any other initialisation stuff here
});
return sharedInstance;
}
シングルトンをバックグラウンドで非同期的にインスタンス化するのは悪い考えではないでしょうか? つまり、共有インスタンスを要求してすぐにそれに依存する場合、dispatch_once がオブジェクトを作成するのにクリスマスまでかかるとどうなるでしょうか? すぐには返らないですよね? 少なくとも、それが Grand Central Dispatch の全体的なポイントのようです。
それで、なぜ彼らはこれをやっているのでしょうか?
ベストアンサー1
dispatch_once()
は完全に同期的です。すべての GCD メソッドが非同期的に動作するわけではありません (たとえば、dispatch_sync()
は同期的です)。 を使用すると、dispatch_once()
次の慣用句が置き換えられます。
+ (MyClass *)sharedInstance {
static MyClass *sharedInstance = nil;
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[MyClass alloc] init];
}
}
return sharedInstance;
}
これに対する の利点はdispatch_once()
、より高速であることです。また、複数のスレッドが sharedInstance の alloc init を実行するのを防ぐため、意味的にもよりクリーンです (すべてのスレッドが同時に試行した場合)。2 つのインスタンスが作成されることは許可されません。 の全体的な考え方は、dispatch_once()
「何かを 1 回だけ実行する」ことであり、まさにそれが私たちが行っていることです。