作者:tingxins
鏈接:http://www.reibang.com/p/82c1104aea6c#nsdateformatter
來(lái)源:簡(jiǎn)書
著作權(quán)歸作者所有唤冈。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)伦糯,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處够庙。
為什么要優(yōu)化NSDateFormatter?
首先蓝纲,過(guò)度的創(chuàng)建NSDateFormatter用于NSDate與NSString之間轉(zhuǎn)換阴孟,會(huì)導(dǎo)致App卡頓,打開(kāi)Profile工具查一下性能税迷,你會(huì)發(fā)現(xiàn)這種操作占CPU比例是非常高的永丝。據(jù)官方說(shuō)法,創(chuàng)建NSDateFormatter代價(jià)是比較高的箭养,如果你使用的非常頻繁慕嚷,那么建議你緩存起來(lái),緩存NSDateFormatter一定能提高效率。
優(yōu)化方式有哪些喝检?
a.延遲轉(zhuǎn)換
即只有在UI需要使用轉(zhuǎn)換結(jié)果時(shí)在進(jìn)行轉(zhuǎn)換嗅辣。
b.Cache in Memory
根據(jù)NSDateFormatter線程安全性,不同的iOS系統(tǒng)版本內(nèi)存緩存如下:
prior to iOS 7
如果直接采用靜態(tài)變量進(jìn)行存儲(chǔ)挠说,那么可能就會(huì)存在線程安全問(wèn)題澡谭,在iOS 7之前,NSDateFormatter是非線程安全的损俭,因此可能就會(huì)有兩條或以上的線程同時(shí)訪問(wèn)同一個(gè)日期格式化對(duì)象蛙奖,從而導(dǎo)致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 7杆兵、macOS 10.9及以上系統(tǒng)版本雁仲,NSDateFormatter都是線程安全的,因此我們無(wú)需擔(dān)心日期格式化對(duì)象在使用過(guò)程中被另外一條線程給修改琐脏,為了提高性能攒砖,我們還可以在上述代碼塊中進(jìn)行簡(jiǎn)化(除去冗余部分)。
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的對(duì)象骆膝,那么我們應(yīng)該監(jiān)聽(tīng)NSCurrentLocaleDidChangeNotification通知祭衩,當(dāng)current locale變化時(shí)及時(shí)更新被緩存的日期格式化對(duì)象灶体。