- 子类B能否直接调用:
- 子类B不能直接调用类A通过扩展添加的隐藏方法。原因是Objective - C中,虽然继承机制会让子类继承父类的实例变量和方法(包括实例方法和类方法),但通过扩展添加的隐藏方法并没有像常规的公开方法那样被显式声明在类的接口部分。编译器在编译时,对于子类,并不会将父类扩展中的隐藏方法视为可直接访问的接口,所以直接调用会导致编译错误。
- 如何让子类B能使用该隐藏方法:
- 方法一:在子类B中重新声明该方法
- 在子类B的.m文件中通过扩展重新声明该方法。例如:
@interface B ()
- (void)hiddenMethod;
@end
@implementation B
- (void)hiddenMethod {
// 调用父类的隐藏方法实现,假设父类实现有意义,这里需要根据实际情况调整
[super hiddenMethod];
// 子类自身的实现代码
}
@end
- 方法二:使用运行时机制
- 在运行时,可以通过
objc_msgSend
函数来调用隐藏方法。首先需要获取方法的SEL
,可以使用NSSelectorFromString
函数来获取对应的SEL
。例如:
SEL hiddenSelector = NSSelectorFromString(@"hiddenMethod");
if ([self respondsToSelector:hiddenSelector]) {
void (*objc_msgSendSuper)(void *, SEL) = (void *)objc_msgSendSuper;
struct objc_super superInfo = {
.receiver = self,
.super_class = class_getSuperclass([self class])
};
objc_msgSendSuper(&superInfo, hiddenSelector);
}
- 这里通过
objc_msgSendSuper
函数,以运行时的方式调用了父类的隐藏方法,同时respondsToSelector:
方法用于确保对象能够响应这个隐藏方法,避免运行时错误。