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


首先,据我所知,init in Objective-C,在功能上类似于构造函数 Java,因为它用于初始化实例变量并准备一个类来做一些工作。它是否正确?

我明白那个 NSObject 器物 init 因此,它不需要在任何声明中声明 .h 文件。

但是如何为给定的类自定义init的实现,例如:

(id) initWithName:(NSString *) name

应该这样的声明作为一部分列出 .h,还是没有必要?它是按惯例完成还是有其他推理?


2040
2017-07-19 15:20


起源



答案:


init 与Java / C ++中的构造函数绝不相似。构造函数始终在创建对象时执行。但执行 init 你决定。如果你不发送 init 之后的消息 alloc 然后它不会执行。

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

如果你从中衍生出来,这将毫无问题地发挥作用 NSObject作为 init 的 NSObject 什么也没做。

您无需添加 init 在头文件中,因为它是从中继承的 NSObject 但是您需要将自定义init方法(未继承)添加到头文件中。注意 init 方法只是具有命名约定的常规方法,但从技术上讲,与其他方法没有区别。

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


12
2017-07-19 15:34



谢谢。如果我使用自定义init方法初始化我的类,是否意味着我应该始终[super init]确保NSObjet的init至少被调用一次? - JAM
是的,即使NSObject的init没有初始化,你也应该这样做。这是一个很好的做法,当你打电话时没有问题。对于大多数其他类,需要调用超类初始化。所以总结是:始终调用基类的初始化方法。 - taskinoor
我不知道为什么我在这里得到了一个downvote。解释我的错误的评论会帮助我。 - taskinoor


答案:


init 与Java / C ++中的构造函数绝不相似。构造函数始终在创建对象时执行。但执行 init 你决定。如果你不发送 init 之后的消息 alloc 然后它不会执行。

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

如果你从中衍生出来,这将毫无问题地发挥作用 NSObject作为 init 的 NSObject 什么也没做。

您无需添加 init 在头文件中,因为它是从中继承的 NSObject 但是您需要将自定义init方法(未继承)添加到头文件中。注意 init 方法只是具有命名约定的常规方法,但从技术上讲,与其他方法没有区别。

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


12
2017-07-19 15:34



谢谢。如果我使用自定义init方法初始化我的类,是否意味着我应该始终[super init]确保NSObjet的init至少被调用一次? - JAM
是的,即使NSObject的init没有初始化,你也应该这样做。这是一个很好的做法,当你打电话时没有问题。对于大多数其他类,需要调用超类初始化。所以总结是:始终调用基类的初始化方法。 - taskinoor
我不知道为什么我在这里得到了一个downvote。解释我的错误的评论会帮助我。 - taskinoor


是的,如果您希望能够调用此个性化初始化方法,则必须声明它(initWithName)。首先想到你必须要做的就是打电话 [super init];


0
2017-07-19 15:25



最好说初始化程序应该调用它的超类的指定初始化程序。指定的初始化程序不一定 -init,在调用指定的初始化程序之前,您可以自由地完成其他工作。 - Caleb
你没有 有 宣布它。它在没有声明的情况下仍然可以调用,但是当你尝试从其他类中使用它时,你会得到编译器警告。 - Richard
我在谈论“initWithName”方法,而不是“init”方法...... - Pierre Watelet