NSDate处理CPU密集型

时间:2014-08-09 13:39:10

标签: ios objective-c optimization nsdate

我的代码中有一个方法来处理需要在NSDate中转换的字符串。 这种方法每秒被称为数百次,显然效率非常低。 如何尽可能地改进?

- (NSDate *)getDateFromString:(NSString *)dateString
{
    NSDateFormatter* formatter = [NSDateFormatter new];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];

    NSDate* date = [formatter dateFromString:dateString];

    if (date == nil) {
        [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
        date = [formatter dateFromString:dateString];
    }
    return date;
}

2 个答案:

答案 0 :(得分:4)

您可以做的第一件事是不要在每次调用时创建格式化程序实例

创建格式化程序非常昂贵。来自Apple的"数据格式指南":

  

创建日期格式化程序并不是一种廉价的操作。如果您可能经常使用格式化程序,则缓存单个实例通常比创建和处理多个实例更有效。

您可以使用static var或属性和延迟加载模式执行此操作。例如,使用static

-(NSDate *)getDateFromString:(NSString *)dateString{
  static NSDateFormatter *formatterWithZone = nil;
  static NSDateFormatter *formatterWithoutZone = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    formatterWithZone = [NSDateFormatter new];
    [formatterWithZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    [formatterWithZone setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
    formatterWithoutZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
  });

  NSDate *date = [formatterWithZone dateFromString:dateString];
  //...
  date = [formatterWithoutZone dateFromString:dateString];
}

或者,如果您要在其他地方使用格式化程序,请将其放在属性中:

@property (nonatomic) NSDateFormatter *formatterWithZone;
@property (nonatomic) NSDateFormatter *formatterWithoutZone;
//...

-(NSDateFormatter *)formatterWithZone{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _formatterWithZone = [NSDateFormatter new];
    [_formatterWithZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    [_formatterWithZone setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
  });
  return _formatterWithZone;
}

-(NSDateFormatter *)formatterWithoutZone{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _formatterWithoutZone = [NSDateFormatter new];
    [_formatterWithoutZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
  });
  return _formatterWithoutZone;
}

-(NSDate *)getDateFromString:(NSString *)dateString{
  NSDate* date = [[self formatterWithZone] dateFromString:dateString];
  //...
  date = [[self formatterWithoutZone] dateFromString:dateString];
}

<强> 更新: 另请查看以下有关NSCalendar -currentCalendar费用昂贵的mrueg's评论(和upvote){{3}}。上述两种技术都可以缓存NSCalendar实例。

答案 1 :(得分:3)

创建日期格式化程序非常昂贵(并且要更改格式)。

制作两个static日期格式化程序变量,每种格式一个,并使用它们而不是每次都创建新的格式化程序。

在dispatch_once块中创建格式化程序。