iOS陷阱--NSDateFormatter的线程安全性
来源:互联网 发布:上海弗洛伦萨小镇 知乎 编辑:程序博客网 时间:2024/06/12 05:17
经常需要将NSDate和NSString进行互转,一般我们会这么写:
static NSDateFormatter *dateFormatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateFormatter = [[NSDateFormatter alloc] init];
});
[dateFormatter setDateFormat:@”yyyy-MM-dd’T’HH:mm:ss”];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@”Asia/Shanghai”]];
return [dateFormatter dateFromString:dateString];
貌似也挺容易的,哈哈经过上面的改造后,你会发现性能得到了显著提升,非常高兴的给老大发布新版本,很快老大又过来把你劈头盖脸地训了一顿:“怎么老是Crash,这么不稳定?赶紧fix”。
一查CrashReport,发现在[dateFormatter dateFromString:dateString]这里出了问题。这就奇怪了?系统函数库也有bug么?
当然不是了,这是因为NSDateFormatter不是线程安全的,请查看https://developer.apple.com/library/mac/documentation/cocoa/conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html,里面列出了线程安全和不安全的类。当多个线程同时访问1个NSDateFormatter对象时,有可能会Crash。
那怎么办?不要泄气,咱们给每个线程准备1个NSDateFormatter,大家就不会打得头破血流了。
解决方案:
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
NSDateFormatter *dateFormatter = threadDictionary[@”mydateformatter”];
if(!dateFormatter){
@synchronized(self){
if(!dateFormatter){
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@”yyyy-MM-dd HH:mm:ss”];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@”Asia/Shanghai”]];
threadDictionary[@”mydateformatter”] = dateFormatter;
}
}
}
发现没有,上面使用了double-check技术哦,哈哈,这里千万不要再用dispatch_once哈。
欢迎关注“iOS开发之道”的微博和微信帐号,一起交流学习。
微博:iOS开发之道 http://weibo.com/u/3652772421
微信:ioszhidao
- NSDate转NSString
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@”yyyy-MM-dd’T’HH:mm:ss”];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@”Asia/Shanghai”]];
return [dateFormatter dateFromString:dateString]; - NSString转NSDate
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:@”yyyy-MM-dd HH:mm:ss Z”];
return [dateFormatter stringFromDate:date];
- 延迟转换并Cache
即只有在UI需要使用转换结果时再执行转换,并将结果缓存起来。 - NSDateFormatter对象只生成1次
static NSDateFormatter *dateFormatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateFormatter = [[NSDateFormatter alloc] init];
});
[dateFormatter setDateFormat:@”yyyy-MM-dd’T’HH:mm:ss”];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@”Asia/Shanghai”]];
return [dateFormatter dateFromString:dateString];
貌似也挺容易的,哈哈经过上面的改造后,你会发现性能得到了显著提升,非常高兴的给老大发布新版本,很快老大又过来把你劈头盖脸地训了一顿:“怎么老是Crash,这么不稳定?赶紧fix”。
一查CrashReport,发现在[dateFormatter dateFromString:dateString]这里出了问题。这就奇怪了?系统函数库也有bug么?
当然不是了,这是因为NSDateFormatter不是线程安全的,请查看https://developer.apple.com/library/mac/documentation/cocoa/conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html,里面列出了线程安全和不安全的类。当多个线程同时访问1个NSDateFormatter对象时,有可能会Crash。
那怎么办?不要泄气,咱们给每个线程准备1个NSDateFormatter,大家就不会打得头破血流了。
解决方案:
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
NSDateFormatter *dateFormatter = threadDictionary[@”mydateformatter”];
if(!dateFormatter){
@synchronized(self){
if(!dateFormatter){
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@”yyyy-MM-dd HH:mm:ss”];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@”Asia/Shanghai”]];
threadDictionary[@”mydateformatter”] = dateFormatter;
}
}
}
发现没有,上面使用了double-check技术哦,哈哈,这里千万不要再用dispatch_once哈。
欢迎关注“iOS开发之道”的微博和微信帐号,一起交流学习。
微博:iOS开发之道 http://weibo.com/u/3652772421
微信:ioszhidao
0 0
- iOS陷阱--NSDateFormatter的线程安全性
- iOS陷阱--NSDateFormatter的线程安全性
- iOS-Foundation框架(NSDateFormatter)
- iOS:应用程序的线程安全性
- iOS:应用程序的线程安全性
- iOS:应用程序的线程安全性
- iOS:应用程序的线程安全性
- 关于NSDateFormatter的线程安全问题
- IOS---------NSDateFormatter的格式字符串
- IOS开发:NSDateFormatter的问题
- iOS NSDateFormatter 日期的使用
- i++的线程安全性
- 类的线程安全性
- i++的线程安全性
- STL的线程安全性
- i++的线程安全性
- i++的线程安全性
- shared_ptr的线程安全性
- 工厂方法模式
- EDMA_CSL库的使用
- poj 3252 Round Numbers(数位dp)
- C语言多文件编译
- IOS中的属性列表----Property List
- iOS陷阱--NSDateFormatter的线程安全性
- swift学习笔记
- xcode6下使用autolayout+sizeclass实践
- 百度面试经历,包括问的问题和我的答案
- 剑指Offer之 - 最小的k个数
- 自定义组件-BreadcrumbTreeView 的使用
- 深入掌握JMS(五):实战Topic
- netperf
- 数据库备份