原文地址:http://www.lianxu.me/blog/2012/03/14/speed-up-nsdateformatter/
如果程序中大量用到NSString转NSDate的代码,不推荐使用NSDateFormatter格式化, 它的速度非常慢。这篇文章介绍如何解决这种情况。
- (NSDate *)dateFromString:(NSString *)string { if (!string) { return nil; } //Wed Mar 14 16:40:08 +0800 2012 static NSDateFormatter *dateformatter=nil; if(dateformatter==nil){ dateformatter = [[NSDateFormatter alloc] init]; NSTimeZone *tz = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; [dateformatter setTimeZone:tz]; [dateformatter setDateFormat:@"EEE MMM dd HH:mm:ss Z yyyy"]; } return [dateformatter dateFromString:string]; }
由于NSDateFormatter内部代码原因,所以格式化字符串代价很大。直接使用NSDateFormatter绝对不是很好的选择,如果你的程序遇到了很多格式时间的代码更是如此。
根据这篇博客 How to Drastically Improve Your App with an Afternoon and Instruments 编写c代码格式化时间字符串速度会提高不少。
- (NSDate *)dateFromISO8601String:(NSString *)string { if (!string) { return nil; } struct tm tm; time_t t; strptime([string cStringUsingEncoding:NSUTF8StringEncoding], "%Y-%m-%dT%H:%M:%S%z", &tm); tm.tm_isdst = -1; t = mktime(&tm); return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]]; }
其实直接字符串处理后利用NSCalendar和NSDateComponents可以更快。
- (NSDate*)dateFromString:(NSString *)string; { if (!string) { return nil; } //Wed Mar 14 16:40:08 +0800 2012 static NSCalendar *gregorian=nil; static NSDateComponents comps=nil; if (gregorian==nil) { gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; comps = [[NSDateComponents alloc] init]; } NSArray *a=[string componentsSeparatedByString:@" "]; if ([a count]==6) { [comps setYear:[[a objectAtIndex:5] intValue]]; int mon=0; NSString *m=[a objectAtIndex:1]; if ([m isEqualToString:@"Jan"]) { mon=1; } else if ([m isEqualToString:@"Feb"]) { mon=2; } else if ([m isEqualToString:@"Mar"]) { mon=3; } else if ([m isEqualToString:@"Apr"]) { mon=4; } else if ([m isEqualToString:@"May"]) { mon=5; } else if ([m isEqualToString:@"Jun"]) { mon=6; } else if ([m isEqualToString:@"Jul"]) { mon=7; } else if ([m isEqualToString:@"Aug"]) { mon=8; } else if ([m isEqualToString:@"Sep"]) { mon=9; } else if ([m isEqualToString:@"Oct"]) { mon=10; } else if ([m isEqualToString:@"Nov"]) { mon=11; } else if ([m isEqualToString:@"Dec"]) { mon=12; } [comps setMonth:mon]; [comps setDay:[[a objectAtIndex:2] intValue]]; @try { NSString *time=[a objectAtIndex:3]; [comps setHour:[[time substringWithRange:NSMakeRange(0, 2)] intValue]]; [comps setMinute:[[time substringWithRange:NSMakeRange(3, 2)] intValue]]; [comps setSecond:[[time substringWithRange:NSMakeRange(6, 2)] intValue]]; } @catch (NSException *exception) { } @finally { } return [gregorian dateFromComponents:comps]; } return [NSDate date]; }
可以看到单独解析字符串的方法,虽然代码要长,但实际上它的速度是最快的。