objective-c – 在一个类别中调用super与在一个子类中调用它相同?

调用[super init]是否在类别中做同样的事情作为子类?如果没有,有什么区别?
为了理解这一点,了解在运行时存储对象的方式可能很重要.有一个类object1,它保存所有的方法实现,并且单独存在一个具有实例变量的存储的结构.类的所有实例共享一个类对象.

当您在实例上调用方法时,编译器会将其转换为objc_msgSend的调用;在类对象中查找方法实现,然后以实例作为参数运行.

对超级的引用在编译时生效,而不是运行时.当您编写[super someMethod]时,编译器会将其转换为调用objc_msgSendSuper而不是通常的objc_msgSend.这将开始寻找超类的类对象中的方法实现,而不是实例的类object.2

一个类别只是向类对象添加方法;它与子类化几乎没有关系.

考虑到这一点,如果你引用一个类别的超级内部,它确实做同样的事情,它将在一个类内 – 方法实现查找超类的类对象,然后运行该实例作为论据.

Itai的帖子更直接地回答了问题,但在代码中:

@interface Sooper : NSObject {}
- (void) meth;
@end

@interface Sooper ()
- (void) catMeth;
@end

@interface Subb : Sooper {}
- (void) subbMeth;
@end

@interface Subb ()
- (void) catSubbMeth;
@end

@implementation Sooper
- (void) meth {
    [super doIt];    // Looks up doIt in NSObject class object
}

- (void) catMeth {
    [super doIt];    // Looks up doIt in NSObject class object
}
@end

@implementation Subb
- (void) subbMeth {
    [super doIt];    // Looks up doIt in Sooper class object
}

- (void) catSubbMeth {
    [super doIt];    // Looks up doIt in Sooper class object
}
@end

1见Greg Parker的写作[objc explain]: Classes and meta-classes

2要注意的一个重要事情是该方法不会在超类的实例上被调用.这是分离方法和数据的方法.该方法仍然被调用在使用该实例的数据的[super someMethod]被写入的同一个实例上,即子类的实例;它只是使用超类的方法实现.

所以调用[super class]到超类对象,找到名为class的方法的实现,并在实例上调用它,将其转换为[self theSuperclassImplementationOfTheMethodNamedClass]的等价物.由于所有的方法都是返回调用它的实例的类,所以你不会得到超类的类,你可以得到自己的类.因此,打电话是对这种现象的一种不好的考验.

整个答案完全忽略了消息传递/方法调用的区别.这是ObjC的一个重要特征,但我认为这可能只是一个笨拙的解释.

相关文章
相关标签/搜索