Mos*_*she 12 subclass objective-c categories
调用是否[super init]在类别中作为子类执行相同的操作?如果没有,有什么区别?
Jos*_*ell 14
为了理解这一点,理解运行时对象的存储方式可能很重要.有一个类对象1,它包含所有方法实现,另外,还有一个结构,其中包含实例变量的存储.类的所有实例共享一个类对象.
在实例上调用方法时,编译器将其转换为对objc_msgSend; 在类对象中查找方法实现,然后以实例作为参数运行.
引用super在编译时生效,而不是在运行时生效.当你编写时[super someMethod],编译器将其转换为调用objc_msgSendSuper而不是通常的调用objc_msgSend.这开始在超类的类对象中寻找方法实现,而不是实例的类对象.2
类只是简单地向类对象添加方法; 它与子类化很少或没有关系.
考虑到所有这些,如果你引用super一个类的内部,它确实做了它在类内部的相同的事情 - 方法实现被查询在超类的类对象上,然后运行该实例作为一个论点.
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
Run Code Online (Sandbox Code Playgroud)
1参见Greg Parker的写作[objc explain]:类和元类
2需要注意的一件重要事情是,不会在超类的实例上调用该方法.这就是方法和数据分离的地方.该方法仍然在[super someMethod]使用该实例的数据编写的同一实例(即子类的实例)上调用; 它只是使用超类的方法实现.
因此,调用[super class]转到超类对象,找到命名方法的实现class,并在实例上调用它,将其转换为等效的[self theSuperclassImplementationOfTheMethodNamedClass].因为所有方法都返回调用它的实例的类,所以你得不到超类的类,你得到了类self.因此,召唤class对这种现象的考验很差.
这整个答案完全忽略了消息传递/方法调用的区别.这是ObjC的一个重要特征,但我认为这可能只是一个已经很尴尬的解释.
不,他们做不同的事情.想象一下这样的类结构:NSObject=> MyObject=> MySubclass,并说你有一个MyObject被调用的类别MyCategory.
现在,调用from MyCategory类似于调用from MyObject,因此super指向NSObject并调用[super init]invokes NSObject的-init方法.但是,从子类调用,super指向MyObject,所以使用superinvokes MyObject的-init方法进行初始化,除非它没有被覆盖,否则它的行为与NSObjects的不同.
这两种行为是不同的,所以在使用类别初始化时要小心; 类别不是子类,而是当前类的添加.
| 归档时间: |
|
| 查看次数: |
3722 次 |
| 最近记录: |