NSDateFormatter 不安全?

2021-05-11  本文已影响0人  天空中的球

今天 Bugly 上发现一个 NSDateFormatter 相关的崩溃,有其奇怪。

问题点
定位

解决:通过加锁的方式可以规避这个问题


+ (NSDateFormatter *)dateFormatterWithFormat:(NSString * _Nullable)format {
    // NSDateFormatter 是不安全的, 此处通过当前线程缓存加锁的方式解决异常 Bugly Crash
    NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
    NSString *key = [NSString stringWithFormat:@"%@%@",kLLDateToolFormatterIden,format];
    NSDateFormatter *dateFormatter = threadDictionary[key];
    if(!dateFormatter) {
        @synchronized(self) {
            if(!dateFormatter) {
                dateFormatter = [[NSDateFormatter alloc] init];
                dateFormatter.dateFormat = format ? format : kLLDateDefaultFormat;
                dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh-Hans_CN"];
                threadDictionary[key] = dateFormatter;
             }
        }
    }
    return dateFormatter;
}

疑惑和反思

static NSDateFormatter *dateFormatter = nil;
+ (NSString *)timestampStringFromRequestDate:(NSDate *)date {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [NSDateFormatter new];
        dateFormatter.dateFormat = @"HH:mm:ss";
    });
    return [dateFormatter stringFromDate:date];
}

所以猜测,原本代码中可能是不是 静态变量 Formatter 在外面被意外接触到,而影响到他被干掉了,从而此处被影响到了,所以更改下:


+ (NSString *)timestampStringFromRequestDate:(NSDate *)date {
    static NSDateFormatter *dateFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [NSDateFormatter new];
        dateFormatter.dateFormat = @"HH:mm:ss";
    });
    return [dateFormatter stringFromDate:date];
}

所以,除了加锁外,暂时也可以这样处理的,感觉对两个疑惑更合理的。

上一篇 下一篇

猜你喜欢

热点阅读