【问题标题】:alloc-init objects within +(void)initialize method to reuse them multiple times+(void)initialize 方法中的 alloc-init 对象以多次重用它们
【发布时间】:2012-05-17 21:54:38
【问题描述】:

我多次使用NSDateFormatter 对象(为特定目的而定制)。由于我不是 objc 专家,所以我想出了三种不同的方法来处理它。

在第一个中,我创建了一个NSDateFormatter 类别并在那里自定义了代码。这是常见的方法,但每次我创建这样的对象时,都会将其放入主自动释放池中。我认为这种行为对非 ARC 和 ARC 代码都有效。

在第二个中,我重写了+(void)initialize 方法并将自定义代码放在那里。这里举个简单的例子:

static NSDateFormatter* dateFormatter = nil;

+(void)initialize
{
    dateFormatter = [[NSDateFormatter alloc] init];
    // other code here
}

最后,我通过如下属性使用延迟加载实例化设置了第三种方法:

-(NSDateFormatter)dateFormatter
{
    if(dateFormatter) return dateFormatter;        
    // alloc-init here
}

说到这里,我想知道哪种方法最适合多次处理对象,以及以这种方式使用+(void)initialize是否正确。

提前谢谢你。

【问题讨论】:

  • 我喜欢第二种或第三种方法,所有方法都适合我。
  • @trojanfoe +1。感谢您的评论。

标签: objective-c ios code-reuse lazy-initialization


【解决方案1】:

后面两种方法都是正确的,但我相信你想把它们放在一起!

static NSDateFormatter *sharedInstance = nil;

+ (NSDateFormatter *)sharedInstance {
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

注意:这样的类称为单例。 Read more

【讨论】:

  • +1 表示支持。第二个呢?谢谢。
  • 嗯,第二个或多或少是共享实例在做什么。我不知道您要添加什么代码,但无论哪种方式,您都必须自己跟踪其状态。这就是为什么将其变成惰性属性会更好的原因。您不必在需要初始化对象时进行跟踪。
【解决方案2】:

基本上,我最喜欢的模式是 mindw0rk 已经给出的模式(我对他的答案投了赞成票)。它的优点是您可以将方法放在NSDateFormatter 上的类别中。我会稍微修改一下:

+ (NSDateFormatter *)sharedInstance {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

这样您就不会在不先初始化的情况下无意中引用sharedInstance

如果您有多个共享实例,您可以使用不同的方法来获取每个实例,例如

+ (NSDateFormatter *)dateFormatterForFoo {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

+ (NSDateFormatter *)dateFormatterForBar {
    static NSDateFormatter *sharedInstance = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDateFormatter alloc] init];
    }
    return sharedInstance;
}

或者,如果每个自定义的日期格式化程序都有自己的子类,它们都可以实现+sharedInstance 以返回正确类的对象。

或者您可以拥有一本日期格式化程序字典:

+ (NSDateFormatter *)customisedFormatterForKey: (NSString*) key {
    static NSDictionary *sharedInstances = nil;
    if (sharedInstance == nil) {
        sharedInstance = [[NSDictionary alloc] initWithObjectsAndKeys: ....];
    }
    return [sharedInstance objectForKey: key];
}

我有一些关于 -initialize 方法的 cmets。

在使用-initialize 时你必须小心一点。它在第一次使用该类之前被调用一次。如果您从不使用该类,它将永远不会被调用。因此,要使您的代码正常工作,您必须确保在开始使用共享实例dateFormatter 之前向NSDateFormatterNSDateFormatter 的实例发送消息之前。请注意,向 dateFormatter 本身发送消息不算数。这是因为它以 nil 开头,因此没有类。

【讨论】:

  • 感谢您的支持。 + 1. 非常有用的答案。根据你写的,它的好处是你可以把方法放在NSDateFormatter上的一个类别中。,你建议把代码放在类别中还是在应用程序的其他部分?也许类别允许具有独立的功能,我错了吗?
  • @Flex_Addicted:像 bny mindw0rk 这样的小方法的优点是你可以把它放在任何地方。它可以在NSDateFormatter 上的类别中使用,或者您可以将其添加到您喜欢的任何课程中,例如您的应用程序委托。如果您将它添加到已经是单例的对象(如应用程序委托),您将使其成为由实例变量支持的实例方法。
猜你喜欢
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 2017-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多