为什么"[self class] == [super class]"?

6

我原本期望[super class]会返回超类的类,但是使用这段代码后,我发现它返回的是当前类的类。

代码

NSLogObject([self class]);
NSLogObject([super class]);
NSLogObject([self superclass]);
NSLogBool([self class] == [super class]);

输出

[self class]: MainMenuScene
[super class]: MainMenuScene
[self superclass]: CCScene
[self class] == [super class]:[YES]

请问有人能解释为什么会发生这种情况吗?我预期它应该返回与[self superclass]相同的值。

宏定义:
-------
#define NSLogBool(i)   NSLog(@"%s:[%@]", #i, (i) ? @"是" : @"否")
#define NSLogObject(o) NSLog(@"%s:[%@]", #o, o)

2
如果我没有说够“class”的话,再来一遍:“Class class class class class!” - James Webster
你不应该在自己的类或宏(或任何其他标识符)中使用苹果前缀。 - JustSid
1
如果我想在输入 NSLog 时让它们显示出来,我应该这样做... :P - James Webster
3个回答

6

[super class] 调用当前实例(即 self)上的 super 方法。如果 self 有一个被覆盖的版本,那么它将被调用并且它看起来会不同。由于您没有覆盖它,因此调用 [self class] 与调用 [super class] 是相同的。


谢谢。我只是有些糊涂,认为一个名为“class”的方法应该在oop的其他部分中表现得不同! - James Webster
我承认在阅读你的问题时,我也曾经掉入同样的陷阱。别担心。 - mprivat
1
即使您没有覆盖它,[self class] 可能与 [super class] 不同,如果 self 是一个子类的实例,该子类覆盖了该方法; 那么它将调用该子类的实现。 - newacct
1
我真的不太理解这个答案。没有super方法。super是一个关键字。 - Rian Rizvi
@RiazRizvi:他们的意思是“超类方法的实现”,只是没有用那么多的话来表达。 - newacct

3

super指的是在超类中的方法实现。如果您没有在您的类中覆盖该方法,则在您的类及其超类中的实现相同。

[super class][self class]都调用在NSObject上定义的相同方法。


1
即使您没有覆盖它,[self class] 可能与 [super class] 不同,如果 self 是一个子类的实例,该子类覆盖了该方法; 那么它将调用该子类的实现。 - newacct

0
虽然mprivat和Sulthan的答案在技术上是正确的,但当前情况有些更加复杂(也更有趣):
考虑对该方法的调用实现。它使用(当然)对象指针。对象指针是指向结构体的指针,该结构体的第一个元素(isa)是指向对象类的指针。class方法(即mprivat和Sulthan已经正确说明的相同方法)遵循这个指针来确定类,即始终为调用对象的类
因此,如果A是B的超类,则由B的实例调用的两个调用[self class][super class]都返回B的类(而不是A的类,因为缺少覆盖!)。

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