爲何要優化NSDateFormatter?
html
首先,過分的建立NSDateFormatter
用於NSDate
與NSString
之間轉換,會致使App卡頓,打開Profile工具查一下性能,你會發現這種操做佔CPU比例是很是高的。據官方說法,建立NSDateFormatter
代價是比較高的,若是你使用的很是頻繁,那麼建議你緩存起來,緩存NSDateFormatter
必定能提升效率。緩存
Creating a date formatter is not a cheap operation. If you are likely to use a formatter frequently, it is typically more efficient to cache a single instance than to create and dispose of multiple instances. One approach is to use a static variable安全
即只有在UI
須要使用轉換結果時在進行轉換。性能優化
根據NSDateFormatter
線程安全性,不一樣的iOS系統版本內存緩存以下:app
prior to iOS 7ide
若是直接採用靜態變量進行存儲,那麼可能就會存在線程安全問題,在iOS 7以前,NSDateFormatter
是非線程安全的,所以可能就會有兩條或以上的線程同時訪問同一個日期格式化對象,從而致使App崩潰。函數
+ (NSDateFormatter *)cachedDateFormatter { NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; NSDateFormatter *dateFormatter = [threadDictionary objectForKey:@"cachedDateFormatter"]; if (!dateFormatter) { dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:[NSLocale currentLocale]]; [dateFormatter setDateFormat: @"YYYY-MM-dd HH:mm:ss"]; [threadDictionary setObject:dateFormatter forKey:@"cachedDateFormatter"]; } return dateFormatter; }
iOS 7 or later工具
在iOS 七、macOS 10.9及以上系統版本,NSDateFormatter
都是線程安全
的,所以咱們無需擔憂日期格式化對象在使用過程當中被另一條線程給修改,爲了提升性能,咱們還能夠在上述代碼塊中進行簡化(除去冗餘部分)。性能
static NSDateFormatter *cachedDateFormatter = nil; + (NSDateFormatter *)cachedDateFormatter { // If the date formatters aren't already set up, create them and cache them for reuse. if (!dateFormatter) { dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setLocale:[NSLocale currentLocale]]; [dateFormatter setDateFormat: @"YYYY-MM-dd HH:mm:ss"]; } return dateFormatter; }
若是緩存了日期格式化或者是其餘依賴於current locale
的對象,那麼咱們應該監聽NSCurrentLocaleDidChangeNotification
通知,當current locale
變化時及時更新被緩存的日期格式化對象。優化
In theory you could use an auto-updating locale (autoupdatingCurrentLocale) to create a locale that automatically accounts for changes in the user’s locale settings. In practice this currently does not work with date formatters.
Apple Threading Programming Guide
若是時間日期格式是固定的,咱們能夠採用C語言中的strptime函數,這樣更加簡單高效。
- (NSDate *) easyDateFormatter{ time_t t; struct tm tm; char *iso8601 = "2016-09-18"; strptime(iso8601, "%Y-%m-%d", &tm); tm.tm_isdst = -1; tm.tm_hour = 0;//當tm結構體中的tm.tm_hour爲負數,會致使mktime(&tm)計算錯誤 /** //NSString *iso8601String = @"2016-09-18T17:30:08+08:00"; //%Y-%m-%d [iso8601String cStringUsingEncoding:NSUTF8StringEncoding] { tm_sec = 0 tm_min = 0 tm_hour = 0 tm_mday = 18 tm_mon = 9 tm_year = 116 tm_wday = 2 tm_yday = 291 tm_isdst = 0 tm_gmtoff = 28800 tm_zone = 0x00007fd9b600c31c "CST" } ISO8601時間格式:2004-05-03T17:30:08+08:00 參考Wikipedia */ t = mktime(&tm); //http://pubs.opengroup.org/onlinepubs/9699919799/functions/mktime.html //secondsFromGMT: The current difference in seconds between the receiver and Greenwich Mean Time. return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]]; }
相關資料: