为什么要优化NSDateFormatter?
首先,过度的创建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
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
解决方案: Cache in Memory
BTNSDateFormatterFactory 利用 NSCache
, 以 stringFormatter+NSLocale的localeIdentifier 形成的string 为key缓存NSDateFormatter
, 不用担心内存管理, 当内存警告时候, 会自动释放NSCache
缓存的对象.
测试
- (void)testExample {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
[self convertDateToStringUsingNewDateFormatter];
[self convertDateToStringUsingBTNSDateFormatterFactoryFormatter];
[self convertDateToStringUsingCLocaltime];
}
#define ITERATIONS (1024*10)
static double then, now;
#pragma test for costs time
- (void)convertDateToStringUsingNewDateFormatter
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
NSDateFormatter *newDateForMatter = [[NSDateFormatter alloc] init];
[newDateForMatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
[newDateForMatter setDateFormat:@"yyyy-MM-dd"];
self.dateAsString = [newDateForMatter stringFromDate:[NSDate date]];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using NSDateFormatter costs time: %f seconds!\n", now - then);
}
- (void)convertDateToStringUsingBTNSDateFormatterFactoryFormatter
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
NSDateFormatter *dateFormatterFactoryFormatter = [[BTNSDateFormatterFactory sharedFactory] dateFormatterWithFormat:@"yyyy-MM-dd" andLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"]];
self.dateAsString = [dateFormatterFactoryFormatter stringFromDate:[NSDate date]];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using BTNSDateFormatterFactory Formatter costs time: %f seconds!\n", now - then);
}
- (void)convertDateToStringUsingCLocaltime
{
then = CFAbsoluteTimeGetCurrent();
for (NSUInteger i = 0; i < ITERATIONS; i++) {
time_t timeInterval = [NSDate date].timeIntervalSince1970;
struct tm *cTime = localtime(&timeInterval);
self.dateAsString = [NSString stringWithFormat:@"%d-%02d-%02d", cTime->tm_year + 1900, cTime->tm_mon + 1, cTime->tm_mday];
}
now = CFAbsoluteTimeGetCurrent();
NSLog(@"Convert date to string using C localtime costs time: %f seconds!\n", now - then);
}
测试结果
测试结果对比使用方式
pod 'BTNSDateFormatterFactory'
github 有任何问题,欢迎issues、pr
网友评论