为什么为单例的静态变量赋值为nil

时间:2012-11-28 21:24:09

标签: objective-c static singleton null

使用它有什么好处:

+ (CardPainter*) sharedPainter {
    static CardPainter* sp = nil;

    if (nil == sp) {
        sp = [[CardPainter alloc] init];
    }

    return sp;
}

而不是:

+ (CardPainter*) sharedPainter {
    static CardPainter* sp = [[CardPainter alloc] init];

    return sp;
}

静态变量初始化只执行一次,所以我看不到前者的优点。

2 个答案:

答案 0 :(得分:1)

嗯,在编译器级别有几个重叠的原因......最简单的想法是静态变量存储在已编译应用程序的专用数据部分中,它只是按原样映射到内存中。因此编译器必须准确知道编译时的内容。任何Objective-C方法调用的结果在编译时都是不可预测的,在定义和实践中 - 你永远不会确定在运行时不会发生“有趣”的事情来改变该方法调用的行为,所以你不要我知道什么会被退回。

这与例如有点不同C ++,由于各种原因(关键的一个是C ++有构造函数,而Objective-C没有)。但即使在C ++中,由于以下几个原因,它仍然不受欢迎:

  1. 构造函数顺序是不可预测的,但是构造函数相互依赖很容易和共同,这意味着程序在运行时可能具有未定义的行为(包括数据损坏或崩溃)。
  2. 许多非平凡对象的初始化可能很昂贵。在发布时一起完成所有这些工作可能会很有效,但它会使您的应用程序启动缓慢,这更糟糕。
  3. 后一点同样适用于Objective-C。你可以避免在发布时做的越多,而是按时进行按需,通常用户体验越好。

    [请注意,“无静态对象实例”规则有一个值得注意的例外,这是@“foo”表单的字符串。这些实际上是在您的应用程序的数据部分中编码为真实实例(特殊NSString子类),它们只是在启动时映射并且按原样神奇地工作。但这是非常仔细的架构和编译器&运行时紧密耦合在这个方面,以确保它一切顺利。它没有也不能普遍适用。 ]

答案 1 :(得分:-2)

因为如果你不问,只要你打电话给“sharedPainter”,你就会初始化“* sp”,丢失任何数据。

所以,如果你问sp是否为n并且答案为FALSE意味着“sp”已经初始化并返回实例。如果答案是真的,那意味着sp没有被初始化,只是在这种情况下你调用了init函数。