objective-c - 在类别中调用 super 与在子类中调用它一样吗?

标签 objective-c subclass categories

调用 [super init] 是否在类别中做与子类相同的事情?如果不是,有什么区别?

最佳答案

为了理解这一点,了解对象在运行时的存储方式可能很重要。有一个类对象1,它保存了所有的方法实现,另外,还有一个存储实例变量的结构。一个类的所有实例共享一个类对象。

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

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

类别只是简单地向类对象添加方法;它与子类化几乎没有关系。

考虑到所有这些,如果您在类别内部引用 super,它确实会做与在类内部相同的事情——在类对象上查找方法实现父类(super class),然后将该实例作为参数运行。

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 class)的实例 上调用。这就是方法和数据分离的用武之地。该方法仍然在编写 [super someMethod] 的同一个实例上被调用,即子类的一个实例,使用该实例的数据;它只是使用父类(super class)的方法实现。

因此对[super class] 的调用转到父类(super class)对象,找到名为class 的方法的实现,并在实例上调用它,将其转换为相当于 [self theSuperclassImplementationOfTheMethodNamedClass]。由于该方法所做的只是返回调用它的实例的类,您不会得到父类(super class)的类,而是得到self 的类。因此,调用 class 是对这种现象的糟糕测试。

整个答案完全忽略了消息传递/方法调用的区别。这是 ObjC 的一个重要特性,但我认为它可能只会混淆本已尴尬的解释。

关于objective-c - 在类别中调用 super 与在子类中调用它一样吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6168058/

相关文章:

objective-c - Swift:替代父类(super class)方法来生成对象

iOS:当应用程序未运行时检测蓝牙设备何时断开连接

objective-c - [SomeClass self] 语法有什么作用?

c++ - 如何分配子类的方法成员指针?

python-3.x - 获取 ABCMeta 的所有注册子类

objective-c - 在运行时获取类的类别详细信息?

ios - 在 StoryBoard 的 TabController 内部使用 Navigation。

php - WooCommerce REST API : Only returns 10 categories

magento - 类别编辑/更新 Magento 中的奇怪问题

java - 如何体现子类的两个对象永不过期?