美文网首页
iOS-在子类中重写及调用父类私有方法

iOS-在子类中重写及调用父类私有方法

作者: LJMagicCoder | 来源:发表于2020-01-17 17:52 被阅读0次

我们平时在使用三方时会比较喜欢根据自己的意愿去封装一下三方,一般都会继承三方创建一些子类,用于对应不同的需求。有时三方会给我们留出接口供我们使用,但有时候并没有。如果我们去给三方直接扩充这些接口是不友好的,特别是CocoaPods上的三方,所以一般我们会在子类里重写三方的方法。

三方中在.h中声明的方法比较好重写,直接在子类里重写方法,如果需要重调父类原有方法可以用super直接调用。而一些私有方法并没有在.h中声明,这时我们也可以直接重写父类方法,但是相对于想要重调父类方法,就不能用super直接调用来实现。这里super只是一个编译器修饰符,是一个指向父类标志,并不是对象的父类实例。所以你再用super调用父类的私有方法是没有作用的。这时我们有几种选择可以帮我们实现父类私有方法的调用。

首先可以用Method Swizzling(方法交换)来帮我们实现,但是我并不喜欢使用这个方法,因为此方法会引起全局的方法指针交换,多人开发中如果没有交流好很容易出现一些纰漏等问题,所以这里我就不具体介绍此方法了。

第二种方法是我们可以利用runtime的消息发送机制,为我们的对象调用其父类的私有方法。主要用到objc_msgSend方法,但是直接调用是不安全的,因为你不能确定父类是否含有这个方法,因为三方也可能进行升级等操作,所以调用之前需要判断父类是否含有此方法,举个例子,代码如下:

// 判断一个父类是否包含某个方法(包含私有方法)
- (BOOL)lj_containsSuperMethod:(NSString *)methodName {
   
  unsigned int outCount = 0;
  Method *methods = class_copyMethodList(class_getSuperclass(self.class), &outCount);
  
  for (int i = 0; i < outCount; i ++) {
      Method method = methods[i];
      SEL methodNameSEL = method_getName(method);
      if ([methodName isEqualToString:NSStringFromSelector(methodNameSEL)]) {
          free(methods);
          return YES;
      }
  }
  
  free(methods);
  return NO;
}

这个方法是利用遍历父类中的所有方法来判断是否包含某一方法,这样做其实也有一定的弊端,比如当这个父类方法很多时,而你又需要频繁调用此方法时就会引起不必要的消耗。如果父类包含此方法就直接利用objc_msgSend发送消息就可以了。例子代码如下:

- (void)privateMethod {
    if ([self lj_containsSuperMethod:@"privateMethod"]) {
        objc_msgSend(self, sel_registerName("privateMethod"));
    }
}

这里调用objc_msgSend方法需要将ENABLE_STRICT_OBJC_MSGSEND设置为NO。

第三种是先获取父类方法,然后利用构建的方式来调用。判断父类是否包含此方法是根据构建出来的方法是否存在来判断的,相比于上一个方法减少了遍历的过程。例子代码如下:

- (void)privateMethod {
    Method method = class_getInstanceMethod(class_getSuperclass(self.class), sel_registerName("privateMethod"));
    void (*super_func)(id,SEL) = (void *)method_getImplementation(method);
    if (super_func) super_func(self, sel_registerName("privateMethod"));
}  

if (super_func) 是判断父类是否包含的此方法,如果含有此方法则调用,否则不调用。

相关文章

  • Objective-c 子类继承父类私有方法

    笔记: 在OC中 如果子类重写了父类的私有方法,父类不会再调用本类的实现,而是直接调用子类的实现。切记,切记。

  • 2018-07-19重写与重载

    重写 当子类继承父类后,拥有了父类成员并且可以调用父类的所有非私有方法,如果子类认为父类所提供的方法不够完美,子类...

  • 多态

    向上转型,隐式转换,自动转型 父类引用指向子类,可以调用子类重写父类方法,及父类派生的方法,但无法调用子类特有的方...

  • 继承和接口

    继承(class 子类 extends 父类)Override:方法重写只改动方法体。 继承不能继承父类私有属性及...

  • NO.19 方法的重写

    重写:子父类出现了一模一样的方法 方法重写注意事项 (1)父类中私有方法不能被重写,因为父类私有方法子类根本...

  • iOS-在子类中重写及调用父类私有方法

    我们平时在使用三方时会比较喜欢根据自己的意愿去封装一下三方,一般都会继承三方创建一些子类,用于对应不同的需求。有时...

  • 04.继承中成员方法的特点

    继承中成员方法的特点&方法重写 A:子类中没有这个方法,调用父类的 B: 子类中重写了这个方法,调用子类的 方法的...

  • Python精简入门学习(十八)

    Python精简入门学习之重写和调用父类方法 -重写重写就是子类中 有一个和父类相同名字的方法 在子类中的方法会覆...

  • 对于重写和调用父类的方法

    所谓的重写就是子类中,有一个和父类相同的名字的方法,在子类中的方法会覆盖掉父类的同名的方法 重写 调用父类的方法:

  • 类的定义与继承

    类 类的继承 重写,子类可以重写父类的方法和属性 子类里,如果重写了父类的方法后,如果还想调用父类的方法,通过su...

网友评论

      本文标题:iOS-在子类中重写及调用父类私有方法

      本文链接:https://www.haomeiwen.com/subject/qvzfzctx.html