共享的NSDateFormatter - 最佳实践?

9
我的团队发现我们在代码库中使用了各种NSDateFormatter对象,并开始研究如何避免在许多不同的地方分配/初始化常见格式化程序的成本和混乱。
我们想到的一个方法是在NSDateFormatter类上创建一个类别,该类别将提供对常规配置格式化程序的静态实例的引用。例如,我们在几个地方使用“短时间”日期格式化程序,并且正在寻找添加以下类方法:
@implementation NSDateFormatter (NSDateFormatter_PDDateFormatters)

static NSDateFormatter * shortTimeFormatter = nil;

+ (NSDateFormatter *) PDSharedShortTimeFormatter {

    @synchronized([NSDateFormatter class]){

        if( shortTimeFormatter == nil){

           // Create new formatter for SHORT times (e.g. 12:00 pm)

           shortTimeFormatter = [[NSDateFormatter alloc] init];
           [shortTimeFormatter setDateStyle: NSDateFormatterNoStyle];
           [shortTimeFormatter setTimeStyle:NSDateFormatterShortStyle];
       }

      return shortTimeFormatter;

   }

  return nil;
}

@end

我对这种方法的问题之一是我们目前没有“保护”NSDateFormatter免遭更改。由于格式化程序在我们的应用程序中基本上是“共享”的,如果另一个对象更改了格式化程序的配置(例如时间/日期样式),这可能会导致问题。
因为我们在内部使用它,所以我不太担心团队误用这个功能的风险(即它是一个小团队,并且有清晰的注释)。
然而,我想知道这里的最佳实践。
有办法返回一个不可变的日期格式化程序的引用吗?如果我返回格式化程序的副本,那是否比我们现在执行的分配/初始化操作更便宜?
还有其他方法吗?
我们将使用这个并运行,但编写“更好”的代码时获得一些反馈总是很好的。
1个回答

9
通常情况下,您不需要担心这个问题。Obj-C允许您操纵几乎任何东西的内部。即使使用@private也不能防止-valueForKey:_thatFunPrivateIvar。如果其他方法都失败了,您可以调用运行时函数。
然而,在这里最简单的解决方法是公开一个API,它在内部使用缓存格式化程序,但不提供对其正在使用的格式化程序的访问。您的代码将使用+ [Formatter shortTimeStringFromDate:]来执行您的示例代码正在执行的操作。相关的格式化程序可以被惰性分配,并且您可以使用可清除内存,以便在内存压力下以LRU方式清除缓存的格式化程序。

在这种情况下,我还考虑为NSDate类添加一个“公共”API:[date PDShortTime]。然后,缓存的NSDateFormatter对象只在幕后访问。感谢您的答案! - thauburger
这也可以作为NSString类别的一个很好的补充,例如:[NSString shortTimeFromDate:]。 - ADAM
“不要担心它”并不是正确的方法:很容易意外修改对象。一定要使用解决方法,这是一个很好的解决方案。 - Greg Maletic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接