Objective-C:init方法应该在.h文件中声明吗?

13
首先,据我的理解,在Objective-C中,init的作用与Java中的构造函数类似,用于初始化实例变量并准备类执行一些操作。这样说是否正确?
我了解到NSObject实现了init方法,因此不需要在任何.h文件中声明它。
但是对于给定类的自定义init的实现呢?例如:
(id) initWithName:(NSString *) name

这样的声明应该列在.h文件中吗?或者说这只是一种惯例,还是有其他原因?

2个回答

13

init 和 Java/C++ 中的构造函数并不相似。构造函数总是在对象创建时执行。但是 init 的执行取决于你。如果你在 alloc 后没有发送 init 消息,则它不会执行。

// init does not execute here
MyObject *obj = [MyObject alloc];

如果您从NSObject派生,那么这将毫无问题地工作,因为NSObjectinit不会执行任何操作。

您不需要在头文件中添加init,因为它继承自NSObject,但您需要在头文件中添加自定义的初始化方法(未继承的方法)。请注意,init方法只是遵循命名约定的普通方法,但从技术上讲,与其他方法没有区别。

如果您没有在头文件中指定自定义的init方法,但向对象发送了该消息,则编译器将生成警告。不会有编译错误。因此,如果您决定忽略警告,则也可以省略该内容。但是,如果实际上未实现该方法,则会发生运行时崩溃。因此最好在头文件中添加所有未继承的方法。


1
谢谢。如果我使用自定义init方法初始化我的类,这是否意味着我应该始终调用[super init]以确保至少调用一次NSObjet的init方法? - James Raitsev
2
是的,即使NSObject的init方法不执行任何初始化操作,您也应始终这样做。这是一个好的实践,当您调用此方法时没有任何问题。对于大多数其他类,调用超类的初始化方法是必须的。因此,总结一下:始终调用基类的初始化方法。 - taskinoor
我不确定为什么我在这里被踩了。一个解释我的错误的评论会帮助我。 - taskinoor

0

如果你想调用这个个性化初始化方法 (initWithName),那么你必须先声明它。并且在该方法的第一步,你需要调用 [super init];


1
更好的说法是,初始化器应该调用其超类的指定初始化器。指定初始化器不一定是 -init,在调用指定初始化器之前,您可以自由地进行其他工作。 - Caleb
你不必声明它。即使没有声明,它仍然可以被调用,但是当你尝试从其他类中使用它时,编译器会发出警告。 - Richard

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