共享 NSDateFormatter - 最佳实践?
我的团队发现我们在整个代码库中使用了各种 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 免遭更改。由于格式化程序本质上是在整个应用程序中“共享”的,因此如果另一个对象要更改格式化程序的配置(例如时间/日期样式),则可能会导致问题。
因为我们在内部使用此功能,所以我不太担心我们的团队滥用此功能的风险(即,这是一个小团队,并且有明确的评论)。
但是,我想知道这里的最佳实践。
有没有办法返回对日期格式化程序的不可变引用?如果我返回格式化程序的副本,这是否比我们现在正在执行的分配/初始化便宜?
这里还有其他方法可以采取吗?
我们将启动并运行这个,但在编写“更好”的代码时获得一些反馈总是好的。
My team found that we were using a variety of NSDateFormatter
objects throughout our code base, and started looking into how we could avoid the cost/confusion of allocating/initializing common formatters in a bunch of separate places.
One idea we had was to create a category on the NSDateFormatter
class that would provide a reference to a static instance of a commonly configured formatter. For example, we were using the "short time" date formatter in several places, and were looking to add the following class method:
@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
One of the issues I have with this approach is that we are not currently "protecting" the NSDateFormatter
from being changed. Since the formatter is essentially "shared" throughout our application, this could potentially cause problems if another object was to change the formatter's configuration (e.g. time/date style).
Because we are using this internally, I'm not overly concerned with the risk of our team misusing this functionality (i.e. it's a small team, and clearly commented).
However, I was wondering about best practices here.
Is there a way to return an immutable reference to the date formatter? If I return a copy of a formatter, is that any less expensive than doing the alloc/inits that we're doing now?
Is there some other approach to take here?
We'll be up and running with this, but it's always good to get some feedback in writing "better" code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常情况下,您不会担心它。 Obj-C 可以让你探索几乎所有东西的有趣内部。即使
@private
也无法防范-valueForKey:_thatFunPrivateIvar
。如果一切都失败了,您可以只调用运行时函数。然而,这里最简单的解决方法是公开一个内部使用缓存格式化程序的 API,但不提供对其正在使用的格式化程序的访问。然后,您的代码将使用 +[Formatter ShortTimeStringFromDate:] 来执行示例代码现在正在执行的操作。有问题的格式化程序可以延迟分配,并且您可以使用可清除内存,以便在内存压力下以 LRU 方式清除缓存的格式化程序。
Normally, you would just not worry about it. Obj-C will let you fiddle with the juicy insides of almost anything. Even
@private
doesn't protect against-valueForKey:_thatFunPrivateIvar
. And if all else fails, you can just invoke runtime functions.However, the simplest workaround here would be to expose an API that internally uses cached formatters, but that provides no access to the formatters it is using. Your code would then use
+[Formatter shortTimeStringFromDate:]
to do what your sample code is doing now. The formatter in question could be lazily allocated, and you could use purgeable memory so cached formatters could be cleared in a LRU fashion under memory pressure.