等效于Objective-C的静态构造函数?


Answers:


129

在使用任何类方法或创建实例之前,第一次使用类时会自动+initialize调用该方法。你永远不要自称。+initialize

我也想沿着珍闻我了解到,可以咬你在路上经过:+initialize由子类继承,并且还要求不执行的每个子类+initialize自己。如果您天真地在中实现单例初始化,则这尤其成问题+initialize。解决方案是像这样检查类变量的类型:

+ (void) initialize {
  if (self == [MyParentClass class]) {
    // Once-only initializion
  }
  // Initialization for this class and any subclasses
}

源自NSObject的所有类都具有+class-class返回Class对象的方法。由于每个类只有一个Class对象,因此我们确实想测试与==运算符的相等性。您可以使用它来过滤应该只发生一次的事件,而对于给定类之下的层次结构中的每个不同类(可能尚不存在),则只过滤一次。

在切线主题上,如果您尚未学习以下相关方法,则值得学习:


编辑:查看@bbum撰写的这篇文章,其中详细说明了以下内容+initializehttp : //www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-许多/

此外,迈克·阿什(Mike Ash)在星期五详细地介绍了有关+initialize+load方法的问答:https : //www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html


5
“如果([self class] == [MyParentClass class])”[self class]在这里是多余的。您可以说if (self == [MyParentClass class])
user102008'7

1
谢谢!您的花絮回答了我的问题,为什么某个特定的静态初始化程序被调用两次。
大卫·斯坦


10

此主题的一些附录:

还有一种使用__attribute指令在obj-c中创建“静态构造函数”的方法:

// prototype
void myStaticInitMethod(void);

__attribute__((constructor))
void myStaticInitMethod()
{
    // code here will be called as soon as the binary is loaded into memory
    // before any other code has a chance to call +initialize.
    // useful for a situation where you have a struct that must be 
    // initialized before any calls are made to the class, 
    // as they would be used as parameters to the constructors.
    // e.g.
    myStructDef.myVariable1 = "some C string";
    myStructDef.myFlag1 = TRUE; 

    // so when the user calls the code [MyClass createClassFromStruct:myStructDef], 
    // myStructDef is not junk values.
}

2
+ load将做同样的事情,并且看起来与Objective-C范例更加同步
Grady Player

@Grady Nope,我特别在帖子中列出了+ load不等效的情况。
理查德·罗斯三世

1
@ RichardJ.RossIII:根据的文档+load+load方法在__attribute__(constructor)函数之前调用
user102008 2013年

1
@ RichardJ.RossIII我不明白您要实现什么,因为该+load方法中的代码先于装饰有该constructor属性的函数中的代码之前执行。你能解释一下吗?也许是在修改您的答案。
山姆

1
@Sam您了解吗,RichardJ.Rosslll在说什么?我想举一个真实的例子……
denis631
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.