使用有什么好处
+ (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;
}
静态变量初始化只执行一次,所以我认为前者没有任何优势。
好吧,在编译器级别上,有几个重叠的原因……最简单的想法是静态变量存储在编译后的应用程序的专用数据部分中,它只是按原样映射到内存中。所以编译器必须在编译时准确地知道这是什么。根据定义和实践,任何Objective-C方法调用的结果在编译时都是不可预测的——你永远不知道在运行时不会发生"有趣"的事情来改变该方法调用的行为,所以你不确定会返回什么。
由于各种原因,这与C++有点不同(一个关键原因是C++有构造函数,而Objective-C没有)。但即使在C++中,它仍然不受欢迎,原因有几个:
- 构造函数的顺序是不可预测的,但构造函数相互依赖是很容易和常见的,这意味着程序在运行时可能会有未定义的行为(包括数据损坏或崩溃)
- 初始化许多不平凡的对象可能代价高昂。在发布时一起做可能会很有效,但这会使你的应用程序启动缓慢,甚至更糟
后一点同样适用于Objective-C。你越能避免在发布时做更多的事情,而是及时按需做,用户体验通常就越好
[请注意,"无静态对象实例"规则有一个值得注意的例外,那就是@"foo"形式的字符串。这些字符串实际上在应用程序的数据部分编码为真实实例(特殊NSString子类)它们只是在发布时被映射进来,然后神奇地按原样工作。但这是经过精心设计的,编译器&运行时在这方面是紧密耦合的,以确保一切顺利进行。它不适用,也不能普遍适用。]
因为如果你不询问,你会在任何时候调用"sharedPainter"时启动"*sp",丢失任何数据。
因此,如果您询问sp是否为零,而答案为FALSE,则表示"sp"已初始化,并返回实例。如果答案是真的,那就意味着sp没有初始化,在这种情况下,您将调用init函数。