在Objective-C中是否有静态构造函数的等价物?

73

我刚接触Objective C,想知道这个语言中是否有静态构造函数的等价物,即类中的静态方法会在该类的第一个实例化之前自动调用。还是说我需要自己调用初始化代码?

谢谢。

3个回答

132

+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的这篇文章,了解更多关于+initialize的内容:https://web.archive.org/web/20201108095221/http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-much/

此外,Mike Ash写了一篇详细的Friday Q&A文章,介绍了+initialize+load方法:https://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html


5
“if ([self class] == [MyParentClass class])”这句话中的[self class]是多余的。你可以直接写成if (self == [MyParentClass class]) - user102008
1
谢谢!你的小贴士解答了我的问题,为什么一个特定的静态初始化器会被调用两次。 - David Stein

51

有一个名为+initialize的类方法,会在使用一个类之前被调用。


谢谢,这正是我在寻找的,但我搜索了“static init”,“static initializer”等,都没有找到它。 - Franklin Munoz
8
在几乎每一个场景中,如果在Java中你会用到“static”这个关键字,那么在Objective-C中你会使用“class”这个关键字。 - Chuck

10

这个话题补充一下:

在 Objective-C 中还有另外一种创建“静态构造函数”的方式,可以使用__attribute指令:

// 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
1
根据+load的文档,+load方法会在__attribute__(constructor)函数之前被调用。 - user102008
1
@RichardJ.RossIII,我不理解您的目标,因为+load方法中的代码在带有 constructor 属性的函数中的代码之前执行。您能否在您的答案中进行说明? - Sam
1
@Sam,你明白RichardJ.Rosslll在说什么吗?我想要一个现实生活中的例子... - denis631
@denis631 我从来没有弄清楚他在说什么。 - Sam
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接