4

次のコードがあります。

  static NSDictionary * errorDescriptions = nil;

+ (NSString *) errorsFromCode: (WPErrorCode) code {

    if(errorDescriptions == nil) {
        errorDescriptions  =  @{[NSNumber numberWithInt: InvalidCar]:  NSLocalizedStringFromTable(@"Car is invalid.", @"WePay", @"validation: invalid car"), ...
    }

    return [errorDescriptions objectForKey: [NSNumber numberWithInt: code]];
}

上記のコードを次のように変更するようアドバイスを受けました。

+ (NSString *) errorsFromCode: (WPErrorCode) code {
    static NSDictionary * errorDescriptions = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        errorDescriptions  =  @{[NSNumber numberWithInt: InvalidCar]:  NSLocalizedStringFromTable(@"Car is invalid.", @"WePay", @"validation: invalid car"), ...
     }
     return [errorDescriptions objectForKey: [NSNumber numberWithInt: code]];
}

なぜそうなのですか?なぜdispatch_onceを使わなければならないのですか?

4

3 に答える 3

6

使用する必要はありませんが、ブロックに入れたものは、スレッドセーフな方法で 1 回だけ実行されます。

if errorDescriptions == nilを使用するかどうかを確認する必要はありませんdispatch_once

于 2013-10-21T20:36:12.317 に答える
4

dispatch_once は、初期化にコストがかかるオブジェクトを作成したり、オブジェクトの初期化中に他のスレッドをブロックしたりするために使用されます。ここでは、これらの状況はいずれも当てはまりません。そのオブジェクトを何回初期化してもかまいませんし、特別な処理が必要なほど高価ではありません。私には無意味に見えます。ブラッドは、2 番目のブロックの if は不必要だと言っています。

于 2013-10-21T20:40:25.217 に答える
1

競合状態を防ぐ可能性が最も高いです。

于 2013-10-21T20:35:01.510 に答える