与模拟器相比,我有一种在设备(iPhone3G)中运行速度非常慢的方法。
虽然模拟器可以在1秒内处理大约100次方法,但设备只能在一秒钟内运行4次。
什么能让它变得如此懒散?
CODE: 注意:该方法从两个日期(事件的开始日期和结束日期)计算人类友好字符串。
-(void)calculateDiaDeInicioYFinTexto
{
NSLog(@"inicio");
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
NSMutableString *auxString = [NSMutableString string];
NSLocale *currLocale = [NSLocale currentLocale];
NSString *stringFormatDay = [NSDateFormatter dateFormatFromTemplate:@"d"
options:0
locale:currLocale];
NSString *stringFormatDayMonth = [NSDateFormatter dateFormatFromTemplate:@"dMMMM"
options:0
locale:currLocale];
NSString *stringFormatDayMonthYear = [NSDateFormatter dateFormatFromTemplate:@"dMMMMYYYY"
options:0
locale:currLocale];
NSDateFormatter *formatterDay = [[NSDateFormatter alloc] init];
[formatterDay setDateFormat:stringFormatDay];
[formatterDay setLocale:currLocale];
NSDateFormatter *formatterDayMonth = [[NSDateFormatter alloc] init];
[formatterDayMonth setDateFormat:stringFormatDayMonth];
[formatterDayMonth setLocale:currLocale];
NSDateFormatter *formatterDayMonthYear = [[NSDateFormatter alloc] init];
[formatterDayMonthYear setDateFormat:stringFormatDayMonthYear];
[formatterDayMonthYear setLocale:currLocale];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponentsNow = [calendar components:(NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit)
fromDate:[NSDate date]];
NSDateComponents *dateComponentsInicio = [calendar components:(NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit)
fromDate:self.diaDeInicio];
NSDate *diaDeInicioTimeless = [calendar dateFromComponents:dateComponentsInicio];
NSDateComponents *dateComponentsFin = [calendar components:(NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit)
fromDate:self.diaDeFin];
NSDate *diaDeFinTimeless = [calendar dateFromComponents:dateComponentsFin];
if ( [diaDeInicioTimeless isEqualToDate:diaDeFinTimeless] ) {
// dates are the same
if ( dateComponentsInicio.year == dateComponentsNow.year ) {
// date is in the current year
[auxString appendFormat:@"%@", [formatterDayMonth stringFromDate:self.diaDeInicio]];
} else {
// date is in another year
[auxString appendFormat:@"%@", [formatterDayMonthYear stringFromDate:self.diaDeInicio]];
}
} else {
// dates are different
if ( dateComponentsInicio.year == dateComponentsFin.year ) {
// years are the same
if ( dateComponentsInicio.month == dateComponentsFin.month ) {
// Months are the same
if ( dateComponentsInicio.year == dateComponentsNow.year ) {
// date is in the current year
[auxString appendFormat:@"%@ - %@",
[formatterDay stringFromDate:self.diaDeInicio],
[formatterDayMonth stringFromDate:self.diaDeFin]];
} else {
// date is in another year
[auxString appendFormat:@"%@ - %@",
[formatterDay stringFromDate:self.diaDeInicio],
[formatterDayMonthYear stringFromDate:self.diaDeFin]];
}
} else {
// Months are different
if ( dateComponentsInicio.year == dateComponentsNow.year ) {
// date is in the current year
[auxString appendFormat:@"%@ - %@",
[formatterDayMonth stringFromDate:self.diaDeInicio],
[formatterDayMonth stringFromDate:self.diaDeFin]];
} else {
// date is in another year
[auxString appendFormat:@"%@ - %@",
[formatterDayMonth stringFromDate:self.diaDeInicio],
[formatterDayMonthYear stringFromDate:self.diaDeFin]];
}
}
} else {
// Years are different
[auxString appendFormat:@"%@ - %@",
[formatterDayMonthYear stringFromDate:self.diaDeInicio],
[formatterDayMonthYear stringFromDate:self.diaDeFin]];
}
}
self.diaDeInicioYFinTexto = auxString;
[formatterDay release];
[formatterDayMonth release];
[formatterDayMonthYear release];
[localPool release];
NSLog(@"Fin");
}
答案 0 :(得分:17)
iOS设备的功能远远低于运行模拟器的计算机。 iOS模拟器不会模拟ARM进程,因此它会全速运行。
此外,此特定方法速度太慢的原因是由于NSDateFormatter
和NSCalendar
对象的创建。这些是相当昂贵的创建,如果你想多次使用它们应该缓存在实例变量/属性中。
答案 1 :(得分:13)
你应该缓存这个变量,它很慢。调用此方法一次。
NSCalendar *calendar = [NSCalendar currentCalendar];
答案 2 :(得分:1)
为INTEL处理器编译模拟器是正常的,当您在模拟器上进行测试时,您的应用程序正在为INTEL构建,并且正在使用您所有计算机CPU的电源。所以它的速度更快。
您可以使用仪器查看哪个部分正在减速执行。
答案 3 :(得分:0)
避免在循环中使用NSDateFormatter。
我通过使用stringWithFormat将date转换为字符串然后使用componentsSeparatedByString来破坏组件来修复它。
NSString *stringDate = [NSString stringWithFormat:@"%@",mydate];
NSArray *stringArray = [stringDate componentsSeparatedByString: @" "];
NSArray *timeArray = [stringArray[1] componentsSeparatedByString: @":"];
通过这样做,我能够在几秒钟内在不到一秒的时间内执行我的循环。
希望这会有所帮助。
答案 4 :(得分:0)
实例化NSDateFormatter和NSCalendar不是非常重要的操作。在我的测试中,在iPhone 4s上创建NSDateFormatter最多可能需要250毫秒。避免重新创建这些对象,如果可能的话,将它们保留为类ivars或静态对象。尽可能重复使用。