5

使用这个有什么好处:

+ (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;
}

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

4

2 回答 2

0

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

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

  1. 构造函数的顺序是不可预测的,但是构造函数相互依赖是很容易和常见的,这意味着您的程序在运行时可能具有未定义的行为(包括数据损坏或崩溃)。
  2. 许多重要对象的初始化可能会很昂贵。在启动时一起完成这一切可能是有效的,但它会使您的应用程序启动缓慢,这要糟糕得多。

后一点同样适用于 Objective-C。您可以避免在发布时做的越多,而是按时按需做,用户体验通常就越好。

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

于 2012-11-29T06:04:00.417 回答
-2

因为如果你不问,你会在任何时候调用“sharedPainter”时启动“*sp”,丢失任何数据。

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

于 2012-11-28T21:34:11.117 回答