And*_*kha 1 inheritance objective-c
请考虑以下代码:
`@interface Parent : NSObject
- (void)whoAmI;
@end
@implementation Parent
- (void)whoAmI
{
NSLog(@"PARENT CALLED");
}
@end
@interface Child : Parent
- (void)test;
@end
@implementation Child
- (void)whoAmI
{
NSLog(@"CHILD CALLED");
}
- (void)test
{
NSLog(@"%@", [super class]);// CHILD!!!! why???
[super performSelector:@selector(whoAmI)];// "CHILD CALLED" why???
}
@end
Run Code Online (Sandbox Code Playgroud)
`
当我调用test方法时,我希望看到父类打印并whoAmI执行父方法.但令人惊讶的是,两次派生类都被调用.任何人都可以解释它为什么会发生,我如何performSelector:在基类?
该super方法只是一种将消息转发到超类的实现代码的方法.但是,self保持不变.实际上,如果您创建一个实例Child,则根本没有实例Parent.您可以通过NSLog的-ING测试此self作为%p检查指针地址; 当调用super方法时,self指针与调用它的子类实例的指针相同:
家长:
- (void)printAddr {
NSLog(@"%p", self);
}
Run Code Online (Sandbox Code Playgroud)
儿童:
- (void)printAddr {
NSLog(@"sub: %p, self");
[super printAddr];
}
Run Code Online (Sandbox Code Playgroud)
如果你打电话,你会看到指针是相同的[aChild printAddr];.
现在让我们将其转化为解决您的具体问题.首先,看看performSelector:方法.它的默认实现是在NSObject中,这个实现很可能用于self调用选择器.因此,即使方法实现是NSObject的方法实现,仍然会在真实对象(您的子类)上调用该方法.如果不是这种行为,performSelector:总是会尝试调用该方法,就好像它是直接在NSObject上实现的,除非你在子类上实现了自己的performSelector:显然,这是错误的行为.
另外,对于该-class方法也是如此.它的默认实现驻留在NSObject上,显然它总是会返回无聊的id [NSObject class],所以它实际上用它self来获取真实对象的类.
您还可以通过在超类上调用另一个方法来测试我在这里所说的内容self.即使您使用super第一个方法调用,第二个方法仍将在您的子类上调用,因为self仍然指向子类:
家长:
- (void)method {
NSLog(@"Parent: method");
[self method1];
}
- (void)method1 {
NSLog(@"Parent method1");
}
Run Code Online (Sandbox Code Playgroud)
儿童:
- (void)method {
[super method];
}
- (void)method1 {
NSLog(@"Child: method1");
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,[aChild method]将输出:
Parent: method
Child: method1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
347 次 |
| 最近记录: |