正确设置方法所需的静态对象的方法

问题描述:

我在NSDate上创建了一个类别,它将NSDate转换为NSString。它使用NSDateFormatter来做到这一点。我发现,分配,然后重新分配格式化每一次在我的应用程序造成明显的延迟(这个类别的使用非常频繁),所以我更新了我的“格式化”的方法是这样的:正确设置方法所需的静态对象的方法

- (NSString *)pretty 
{ 
    static NSDateFormatter *formatter = nil; 

    if (formatter == nil) 
    { 
     formatter = [[NSDateFormatter alloc] init]; 
     [formatter setDateStyle:NSDateFormatterLongStyle]; 
     [formatter setTimeStyle:NSDateFormatterNoStyle]; 
    } 

    return [formatter stringFromDate:self]; 
} 

这是正确的在Cocoa中处理静态变量的方法?这是一个泄漏(没有deallocalloc)?做这样的事情有更好的方法吗?谢谢!

+0

请注意,你应该用一个前缀命名你的方法;即'MyApp_pretty'什么的。防止碰撞。 – bbum 2011-06-01 19:36:42

您正在有效地创建一个单身人士。除非不会在应用程序的整个运行会话中使用,否则不要担心内存使用情况。即使它只是间歇性地使用,留下一个日期格式化程序也不会成为问题。

I.e.就像单身人士一样,在应用程序终止之前不要担心释放对象。

如果pretty被多线程攻击(并假设NSDateFormatter本身是线程安全的 - 我没有检查文档,因此,不编写代码而没有验证线程安全性),那么你我想保护初始化。

static dispatch_once_t onceMark; 
static NSDateFormatter *formatter = nil; 
dispatch_once(&onceMark, ^{ 
     formatter = [[NSDateFormatter alloc] init]; 
     [formatter setDateStyle:NSDateFormatterLongStyle]; 
     [formatter setTimeStyle:NSDateFormatterNoStyle]; 
}); 
+0

在iOS 4之前呢? – user102008 2011-06-27 21:10:44

+0

使用锁,@synchronized()或其他一些序列化原语。 – bbum 2011-06-27 21:34:20

我相信你应该保留格式化程序以免泄漏,下次使用格式化程序时,你可能会发生虚假的崩溃。

对于它的价值,我在NSDateFormatter对象的类别中做了这件事情,因为我也观察到NSDateFormatter分配速度减慢了我的应用程序。

+6

不需要,因为alloc,保留计数已经是+1。 – 2011-06-01 17:45:39

+0

@Mark不会自动设置一个积极的保留计数? – Stussa 2011-06-01 17:53:27

+0

我认为如果'formatter'属性是一个属性,并且使用点符号来分配,那么只会增加保留计数......我的经验是,您必须在这里保留它。虽然这可能被认为是sl,不驯的,但在这种情况下额外的保留并不是那么糟糕:无论如何,您都希望该对象在程序的整个生命周期中继续存在。无论如何,我很高兴能够开悟。 :-)我有时候仍然会遇到内存管理问题! NARC; – 2011-06-01 17:58:20