MST

星途 面试题库

面试题:Objective-C 扩展隐藏方法的实现及调用场景

在Objective-C里,使用扩展为类添加隐藏方法后,阐述该隐藏方法在不同类继承结构以及运行时的调用机制。假设存在类A及其子类B,类A通过扩展添加了隐藏方法,子类B能否直接调用该方法?若能,说明原因及调用方式;若不能,说明如何让子类B也能使用该隐藏方法。
31.3万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试
  1. 子类B能否直接调用
    • 子类B不能直接调用类A通过扩展添加的隐藏方法。原因是Objective - C中,虽然继承机制会让子类继承父类的实例变量和方法(包括实例方法和类方法),但通过扩展添加的隐藏方法并没有像常规的公开方法那样被显式声明在类的接口部分。编译器在编译时,对于子类,并不会将父类扩展中的隐藏方法视为可直接访问的接口,所以直接调用会导致编译错误。
  2. 如何让子类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:方法用于确保对象能够响应这个隐藏方法,避免运行时错误。