这些都是相当简单的问题,但在继续之前我想在脑子里找到...
@interface BasicTire : NSObject {
}
@end
@interface SnowTire : BasicTire {
}
@end
当您调用[SnowTire init]时,包含的[super init]调用[BasicTire init],然后调用[NSObject init]? (即运行到父/超类的级联。
当你[SnowTire alloc]创建一个新对象时,它包含了其superClass的功能。我是否正确地认为你没有创建以某种方式链接的多个对象(例如SnowTire> BasicTire> NSObject)。
只是想检查......
加里
答案 0 :(得分:3)
是的,通常初始值设定项调用超类初始值设定项。这在init
方法的实现中明确完成。虽然可以调用同一类或其超类的其他初始值设定项,但有必要确保"designated initializer"始终被调用。
如果一个对象没有实现init
(或者有问题的初始化程序),那么就会调用超类中的一个(就像使用任何其他方法一样)。这不是很少,因为在Objectve-C中,实例变量总是初始化为零(在alloc
中),因此通常没有必要实现专门的init
。
alloc
只分配内存并设置确定对象类的对象的“isa指针”。你得到的是一个未初始化的对象(不是链表),它有所有实例变量(包括超类)的空间。
答案 1 :(得分:2)
是。每个初始化程序必须调用超类的指定初始化程序,一直到NSObject
。每个初始化程序将超级初始化程序的结果分配给self也很重要。由于初始化程序不需要返回将初始化消息发送到的相同实例。
是。 alloc
在堆上为对象实例变量初始化了足够的内存,并用零清除此内存。这样所有指针都将是nil
,布尔值false
等等。然后它将isa
指针设置为新对象的类。
答案 2 :(得分:1)
当你调用[SnowTire init]时,包含的[super init]调用[BasicTire init],然后调用[NSObject init]? (即一个级联运行到父/超类。
您同时实施-[SnowTire init]
和-[BasicTire init]
,因此您只需查看您的实施即可:
-[SnowTire init]
使用[super init]
来致电-[BasicTire init]
。-[BasicTire init]
使用[super init]
来致电-[NSObject init]
。 [super init]
总是调用下一个可用的实现,即使它不在您的直接超类中。如果您未实施-[BasicTire init]
,则[super init]
中的-[SnowTire init]
表达式将调用-[NSObject init]
。这没关系,因为你显然认为BasicTire不需要任何初始化。 (如果确实如此,那么你遗漏-[BasicTire init]
就是一个错误。)
当你[SnowTire alloc]创建一个新对象时,它包含了其superClass的功能。我是否正确地认为你没有创建以某种方式链接的多个对象(例如SnowTire> BasicTire> NSObject)。
是。每个对象都有一个类(在一个名为isa
的变量中,如“此实例是 SnowTire”),每个类都有一个超类和一个元类。与所有Objective-C方法和C函数一样,-alloc
和-init
每个只返回一个东西 - 在这种情况下,一个实例有一个类。
因此,例如,当您向雪地轮胎发送gripTheSnow
消息时,它会使用SnowTire实施该方法。如果你发送了一条retain
消息,那么你没有在SnowTire中实现retain
而你没有在BasicTire中实现它,所以它使用了NSObject的实现。运行时从对象的类(在本例中为SnowTire)开始,在类层次结构的直线上搜索,以NSObject等根类结束。