ios-利用消息发送机制进行alloc和init的消息发送以及给父类发消息

首先我们先看一下我们平时创建一个对象是这么创建的

Person * p = [[Person alloc]init];

其实做的就是两件事情,一个就是去调用alloc方法,另一个就是去调用init方法,利用消息发送机制来做的话,其实就是这样子,其中sel_registerName其实就是使用Objective-C运行时系统注册一个方法,将方法名称映射到选择器,并返回选择器值。

    Person * p1 = objc_msgSend([Person class], sel_registerName("alloc"));

    p1 = objc_msgSend(p, sel_registerName("init"));

为了证明这一点,我们可以利用clang -rewrite-objc去把OC的代码转换为C/C++的代码,可以查看到转换为C/C++的函数,下面就是去创建一个Person对象调用的方法
这里写图片描述

如果说我们的Person类当中我们定义了方法,如果我们想要用消息发送机制去调用方法的话,我们可以这么做

Person类中的方法

-(void)eatWithName:(NSString *)name store:(NSString *)store
{
    NSLog(@"%@---%@",name,store);
}

利用消息发送机制

objc_msgSend(p1, sel_registerName("eatWithName:store:"),@"鱼头",@"粗粮杂货店");

执行结果

这里写图片描述

紧接着,如果我们创建了一个子类,并且在子类中重写了父类的方法,但是我们想要让子类中调用方法的时候调用的是父类的方法,我们需要去调用class_getSuperclass方法,首先先看下子类当中的方法

-(void)eatWithName:(NSString *)name store:(NSString *)store
{
    NSLog(@"子类的方法");
}

调用父类的方法

ZXPerson * p = [[ZXPerson alloc]init];

 //objc_getClass 返回一个类对象
 //class_getSuperclass 返回一个类的父类
struct objc_super  psuper = {p,class_getSuperclass(objc_getClass("ZXPerson"))};
 //给父类发消息
    /*
     1、objc_super 结构体
     2、方法编号
     */
objc_msgSendSuper(&psuper, @selector(eatWithName:store:),@"哈哈",@"嘿嘿");

其中关于objc_super的结构体如下所示,有一个实例对象的成员以及传入一个super class

struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained _Nonnull id receiver;

    /// Specifies the particular superclass of the instance to message. 
    //首先__cplusplus是C++编译器内部定义的宏,如果使用的C编译器,__cplusplus宏不会被定义。它可以作为区分使用的是C编译器还是C++编译器的标志
    //__OBJC2__其实就是判定是不是使用objc2.0,OC也是有版本的,当前版本为2.0。
#if !defined(__cplusplus)  &&  !__OBJC2__
    /* For compatibility with old objc-runtime.h header */
    __unsafe_unretained _Nonnull Class class;
#else
    __unsafe_unretained _Nonnull Class super_class;
#endif
    /* super_class is the first class to search */
};

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zcmuczx/article/details/80276114