在 Objective-C 中,[self class]
和 [super class]
都用于获取对象的类信息,但它们在运行时的行为略有不同。理解它们的区别有助于更好地掌握 Objective-C 的消息传递机制和继承关系。让我们详细解释这两个调用的区别。
[self class]
当你在一个对象方法中调用 [self class]
时,实际上是向对象发送了一条 class
消息。这个消息的接收者是 self
,即当前对象。self
是指向当前实例的指针,方法的调用是通过对象本身的 isa
指针找到对应的类方法。
示例代码
@interface MyClass : NSObject
- (void)printClass;
@end@implementation MyClass
- (void)printClass {NSLog(@"[self class]: %@", [self class]);
}
@end
在这个示例中,[self class]
直接调用了 self
对象的 class
方法。假设 self
是 MyClass
类的一个实例,[self class]
将返回 MyClass
。
[super class]
当你在一个对象方法中调用 [super class]
时,super
不是一个指向当前对象的指针,而是一个编译器指示,告诉编译器从父类的实现开始查找方法,而不是从当前类。这意味着尽管方法的接收者仍然是当前对象,但方法的查找从父类开始。
示例代码
@interface MyClass : NSObject
- (void)printClass;
@end@implementation MyClass
- (void)printClass {NSLog(@"[super class]: %@", [super class]);
}
@end
在这个示例中,[super class]
会调用 NSObject
的 class
方法,因为 MyClass
继承自 NSObject
。然而,由于 class
方法并未被重写,所以最终效果与 [self class]
相同。
具体区别
-
方法查找起点:
[self class]
:从当前类开始查找class
方法。[super class]
:从父类开始查找class
方法。
-
结果:
- 在绝大多数情况下,如果
class
方法没有被重写,[self class]
和[super class]
的结果是相同的,都返回对象的实际类。 - 如果在子类中重写了
class
方法,[self class]
会调用重写的方法,而[super class]
则会调用父类的方法。
- 在绝大多数情况下,如果
重写 class
方法的示例
@interface MyClass : NSObject
@end@implementation MyClass
- (Class)class {return [NSString class];
}
@end@interface SubClass : MyClass
@end@implementation SubClass
- (void)printClass {NSLog(@"[self class]: %@", [self class]);NSLog(@"[super class]: %@", [super class]);
}
@endint main(int argc, const char * argv[]) {@autoreleasepool {SubClass *obj = [[SubClass alloc] init];[obj printClass];}return 0;
}
在这个示例中,MyClass
重写了 class
方法,返回 NSString
类。SubClass
继承自 MyClass
并添加了 printClass
方法。运行这个程序会输出:
[self class]: NSString
[super class]: NSString
由于 SubClass
继承了 MyClass
的 class
方法,所以无论是 [self class]
还是 [super class]
,最终调用的都是 MyClass
中重写的 class
方法。
总结
[self class]
:发送class
消息给当前对象,方法查找从当前类开始。[super class]
:发送class
消息给当前对象,但方法查找从父类开始。
在大多数情况下,如果 class
方法没有被重写,它们的结果是相同的。但如果 class
方法被重写,它们的行为会有所不同,[self class]
会调用当前类的重写方法,而 [super class]
会调用父类的方法。