为什么分配或初始化NSDateFormatter认为“昂贵”?

当他们说这样很贵的时候,人们的意思是什么? 我为中间存储创build了很多瞬态对象的实例(NSString和NSDate是典型的)。 我怎么知道我的程序使用NSDateFormatter是否过度使用它?

到目前为止,我倾向于创build相当于单例的东西,但是我的偏好是将其封装到与其相关的其他对象中,所以我可以使用自引用。

缺less运行性能testing,我正在寻找一个更好的“经验法则”理解为什么我应该或不应该这样做。

当像这样的东西被认为是昂贵的,这并不一定意味着你不应该这样做,这只是意味着避免在需要尽快摆脱方法的情况下进行。 例如,当iPhone 3G是最新的设备时,我正在编写一个带有UITableView的应用程序,这个应用程序在每个单元格中显示格式化的数字(我可能会补充说,当我在iOS开发初学者时,这个数字已经回来了)。 我的第一次尝试是以下几点:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *reuseIdentifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath]; MyManagedObject *managedObject = [self.managedObjects objectAtIndex:indexPath.row]; NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; [cell.textLabel setText:[managedObject title]]; [cell.detailTextLabel setText:[numberFormatter stringFromNumber:[managedObject amount]]]; return cell; } 

这个代码的滚动性能是可怕的。 帧率下降到大约15 FPS,因为我每次分配一个新的NSNumberFormatter tableView:cellForRowAtIndexPath:被击中。

我通过更改代码来修复它:

 - (NSNumberFormatter *)numberFormatter { if (_numberFormatter != nil) { return _numberFormatter; } _numberFormatter = [[NSNumberFormatter alloc] init]; [_numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; return _numberFormatter; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *reuseIdentifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath]; MyManagedObject *managedObject = [self.managedObjects objectAtIndex:indexPath.row]; NSNumberFormatter *numberFormatter = [self numberFormatter]; [cell.textLabel setText:[managedObject title]]; [cell.detailTextLabel setText:[numberFormatter stringFromNumber:[managedObject amount]]]; return cell; } 

这里的区别是,我懒惰地加载了一个伊娃的NSNumberFormatter ,以便tableView:cellForRowAtIndexPath:每一次运行不再分配一个新的实例。 这个简单的变化把滚动性能提高到了大约60 FPS。

这个具体的例子不再那么重要,因为新的芯片能够处理分配而不影响滚动性能,但总是尽可能高效。

前段时间我也有同样的问题。 我在一些我正在使用的应用程序上运行了Instruments,我发现以前的开发人员正在为每个自定义日志创build一个新的NSDateFormatter。 由于每个屏幕他们用来logging约3行。 该应用程序只用了大约1秒,只创buildNSDateFormatters。

简单的解决scheme是将date格式化程序实例作为属性保留在类中,并将其重用于每个日志行。

经过一些微不足道的思考,我已经来到一个“工厂”来处理基于格式和区域设置的NSDateFormatters的重用。 我请求格式和语言环境的date格式化程序,我的课程给已经加载的格式化程序给我。 良好的性能调整,你应该尝试。

PS:也许有人想testing它,所以我公开: https : //github.com/DougFischer/DFDateFormatterFactory/blob/master/README.md