在你的一个Objective-C课程中实现+ initialize或+ load方法时,你总是从这种警卫开始吗?:
@implementation MyClass
+ (void)initialize {
if (self == [MyClass class]) {
...
}
}
...
@end
看起来像+ load和+ initialize中的代码通常只想执行一次。所以这有助于避免在子类加载/初始化时重复执行。
我想我只是想从一些ObjC巫师那里得到一些强化,这是必要的/普遍的做法......
这是什么常见的智慧?你会建议总是这样做吗?
对于+ load和+ initialize,你的建议是否相同,或者它们的处理方式是否存在差异?
感谢。
答案 0 :(得分:5)
快速回答是:否。
可以在Apple开发人员邮件列表中找到in-depth discussion of this matter。
它的要点是:
+initialize
。
+initialize
方法将不会触发相关的KVO通知。
有关第2点的示例,请务必阅读上述主题中的this post。
答案 1 :(得分:4)
是的,如果要初始化只应初始化一次的全局变量,则应在初始化和加载方法中执行此操作。
那就是说,有很多情况下你可以避免它......
如果需要对每个类的每个继承者执行工作,则不应使用此条件包装:
还有一些情况你不必费心:
“幂等”部分是相关的。初始化器应该只是设置初始状态(每次都应该相同)。在一个好的初始化器中,重复应该无关紧要。虽然我认为如果你忘记在 重要的情况下将方法包装在条件中,这可能会很烦人。
已编辑的补充:一种不同的方法,可以正确反映任何初始化一次性要求,即测试您的初始化属性是否已初始化。即。
id myGlobalObject = nil;
+(void)initialize
{
if (myGlobalObject == nil)
{
myGlobalObject = [[MyGlobalClass alloc] init];
}
}
答案 2 :(得分:1)
YES !!!!
因为可以多次调用类的initialize方法。例如当你在父类中实现初始化,并且没有在子类中实现时,那么先调用子类,父类的初始化将被调用两次。
@implementation BaseClass
+ (void)initialize
{
NSLog(@"BaseClass initialize self=%@, class=%@", self, [BaseClass class]);
}
@end
@interface SubClass : BaseClass
@end
@implementation SubClass
// don't implement the initialize method
@end
==================
现在首先调用SubClass,就像
一样[SNSBaseSubLogic alloc]
查看调试控制台,输出:
BaseClass initialize self=BaseClass, class=BaseClass
BaseClass initialize self=SubClass, class=BaseClass
所以,你必须使用
+ (void)initialize
{
if (self == [BaseClass class]) {
NSLog(@"BaseClass initialize self=%@, class=%@", self, [BaseClass class]);
}
}
确保方法体执行一次。