使用dispatch_once

4

I have the following code:

  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?
3个回答

6

您不必使用它,但是您放置在块中的内容将只以线程安全的方式执行一次。

如果您将使用dispatch_once,则不需要也不应该使用if errorDescriptions == nil检查。


4

dispatch_once用于创建初始化费时的对象,或在对象初始化期间阻止其他线程。但这些情况都不适用于此处。无论你初始化该对象多少次,它都不需要特殊处理,也不需要花费昂贵的成本。对我来说,这看起来毫无意义。布拉德正确地指出第二个块中的if是多余的。


如果您没有使用ARC,那么在竞态条件下可能会泄漏创建的第一个字典。 - Brad Allred
如果这段代码没有使用 ARC,那么当第二次运行该方法时,它会崩溃。因为该字典存在于自动释放池中。- Brad Allred - jscs
是的,它应该是@[@{...} retain],因为字面语法会创建一个自动释放的对象。 - Jano
@JoshCaswell 也说得很好 :) 但是如果你发现自己正在处理非ARC代码,还是要记住这一点。 - Brad Allred

1
最有可能是为了防止竞态条件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接