Objective-C 与许多其他面向对象的语言不同,它使对象创建成为一个明确的两阶段过程,分配和初始化。
如果您熟悉 Java、C# 和 C++ 等语言,那么对象创建的分配部分与初始化是不可分割的。因此,例如在 Java 中,您可以编写:
class Tree {
// constructor/initialiser
public Tree ()
{
// whatever is needed to initialise a Tree
}
}
...
Tree myTree = new Tree(); // allocate and initalise a tree
Java 的new
表达式为 a分配内存Tree
,然后调用构造函数来正确设置该内存。
上述语言认识到分配和初始化只是真正单一操作的两个部分:对象创建。
在 Objective-C 中,上面的例子是:
@implementation Tree
// constructor/initialiser
(id) init ()
{
// whatever is needed to initialise a Tree
}
@end
...
Tree *myTree = [[Tree alloc] init]; // allocate and initalise a tree
在这里,您理论上可以将分配和初始化分开,但不建议这样做。这样做的原因[Tree alloc]
通常不会返回完全形成的Tree
,它会分配一些内存并将其标记为 aTree
但任何由 拥有的实例变量,或者未初始化Tree
的超类-必须调用初始化。如果您将这两个操作分开,那么您可能会有不完整的对象,这些对象的行为将无法按预期进行。因此,尽管您可以将它们分开,但这样做非常不明智,以至于 Apple 的州文档:Tree
init
init
消息与同一行代码中的init
消息耦合alloc
那就是Apple告诉你一个小谎言,以防止你犯下一个大错误。
Objective-C 也提供了单一的创建操作形式:
Tree *myTree = [Tree new]; // alloc + init
然而,与 Java等不同的是,如果您编写一个带有参数的初始化程序,您不会自动获得一个带有new
参数的版本 - 您需要自己编写(作为使用的类方法alloc
和带有参数的初始化程序)。
高温高压