runtime事件传递之super的手动内部实现

2017-04-28  本文已影响0人  小鱼闯江湖

OC的事件传递会从子类开始寻址,如果没有找到事件,则向它的父类找,还没找到,则会向父类的父类找,一直找到NSObject.

而众所周知,调用父类方法需要用到super关键字.当我们知道的一个对象包含有一个私有方法时,如果需要改写它的私有方法,那么我们就需要调用到父类的方法super关键字.但是此时调用super,Xcode会发脾气啦~"父类找不到这个方法!"

此时如果我们想调用父类的方法就需要一定手段啦!

进入头文件#import <objc/message.h>查看,平时用到的函数

id objc_msgSend(id self, SEL op, ...)

下方有另外一个函数

id objc_msgSendSuper(struct objc_super *super, SEL op, ...)

那么线索来了,这个函数该怎么用呢?

平日里我们都是用的self,此时多出一个结构体struct objc_super *super

点进去发现,原来结构体是这样介绍的:

struct objc_super {

  /// 指定一个现有的对象.

  __unsafe_unretained id receiver;

  /// 指定上面的对象的父类.

  #if !defined(__cplusplus)  &&  !__OBJC2__ //如果未定义OC2.0和C++,则定义它

  /* 旧款的runtime,我们可以忽略不计 */

  __unsafe_unretained Class class;

  #else

  //新款的class,需要赋值该对象的父类

  __unsafe_unretained Class super_class;

  #endif

  /* super_class is the first class to search */

};

好了,那么我们就开始手动将super关键字实现一下吧!当想手动调用UIViewController的super时需要以下几步:

//定义一个结构体

struct objc_super superclass = {self,self.superclass};

此时,superclass就是我们想要的啦!

如果我们想调用[super viewDidLoad]呢?

代码如下:

((void(*)(struct objc_super *,SEL))objc_msgSendSuper)(&superclass,@selector(viewDidLoad));

*号使用取地址符号即可

那么带参数呢?继续强转向后面拼接参数就可以啦~

------------------------------我 是 有 底 线 的------------------------------

上一篇下一篇

猜你喜欢

热点阅读