dispatch_once有什么更短的替代方案吗?

时间:2014-04-10 10:01:50

标签: ios objective-c grand-central-dispatch

有没有更短的版本?感觉好像很多样板。

我投入了几个我认为很乏味的例子

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    static id instance;
    dispatch_once(&onceToken, ^{
        instance = [self new];
    });
    return instance;
}

+ (NSString *)RFC2822StringFromDate:(NSDate *)date
{
    static NSDateFormatter *formatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        formatter = [NSDateFormatter new];
        formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
        formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
        formatter.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss Z";
    });

    return [formatter stringFromDate:date];
}

1 个答案:

答案 0 :(得分:2)

我刚做了一个小宏,基本上可以让你写很短的东西

+ (instancetype)sharedInstance
{
    return dispatch_once_and_return(id, [self new]);
}

此语义

也支持块
+ (NSString *)altRFC2822StringFromDate:(NSDate *)date
{
    NSDateFormatter *formatter = dispatch_once_and_return(NSDateFormatter *, ^{
        NSDateFormatter *f = [NSDateFormatter new];
        // setup formatter
        return f;
    }());

    return [formatter stringFromDate:date];
}

(诀窍是在块之后添加(),它基本上会立即执行块。)

#define dispatch_once_and_return(type, value) ({\
    static type cachedValue;\
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        cachedValue = value;\
    });\
    cachedValue;\
})