专栏首页老沙课堂消息转发及super

消息转发及super

消息发送

动态解析

**消息转发的时候。由于oc的底层原理是消息机制,所以可以添加c语言函数等 **

//定义一个c函数
void test2(id self,SEL _cmd) {
    NSLog(@"%s",__func__);
}
复制代码
// 动态解析
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if ([self respondsToSelector:sel]) {
        return [super resolveInstanceMethod:sel];
    }
    // 动态添加实现方法
	  //函数名即函数地址
    class_addMethod(self, sel, (IMP)test2, "v@:");
    return YES;
}
复制代码

消息转发

消息转发的时候。由于oc的底层原理是消息机制,所以可以返回对象或者是类都可以

super

super 底层原理

NSLog(@"%@",[super class]);
        
NSLog((NSString *)&__NSConstantStringImpl__var_folders__9_b_xp2qr12j348_dq41f7zqqh0000gn_T_Student_8019bf_mi_0,((Class (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("Student"))}, sel_registerName("class")));
复制代码

精简后代码

struct rw_objc_super {
    struct objc_object *object;
    struct objc_object *superClass;
};

objc_msgSendSuper((struct rw_objc_super){(id)self,
                        (id)class_getSuperclass(objc_getClass("Student"))}
                          ,sel_registerName("class")));
复制代码

大概就是调用objc_msgSendSuper方法 然后传入个super的结构体 然后调用class方法

然后我们在源码中看一下objc_msgSendSuper的注释

/**
 * Sends a message with a simple return value to the superclass of an instance of a class.
 *
 * @param super A pointer to an \c objc_super data structure. Pass values identifying the
 *  context the message was sent to, including the instance of the class that is to receive the
 // 这句  消息是从super开始查找。而不是self;
 *  message and the superclass at which to start searching for the method implementation.
 * @param op A pointer of type SEL. Pass the selector of the method that will handle the message.
 * @param ...
 *   A variable argument list containing the arguments to the method.
 *
 * @return The return value of the method identified by \e op.
 *
 * @see objc_msgSend
 */
OBJC_EXPORT id _Nullable
objc_msgSendSuper(struct objc_super * _Nonnull super, SEL _Nonnull op, ...)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
复制代码

所以通过注释可以知道,objc_msgSendSuper其实接收器还是self,只不过在消息传递中,直接从super中查找,而不是自身的class/meta-class。因为class 的实现使用过object_getClassName(self); 传入的是self,所以返回的是self的class。

@dynamic 告诉编译器不要自动生成setter和getter的实现

本文分享自微信公众号 - 老沙课堂(gh_f73a6b772d4f),作者:rui4u

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • super(二) 以及内存分布

    在ViewController 书写以下代码。问是否能编译通过,如果可以输出什么是什么?

    老沙
  • isa详解(一)isa结构

    为什么要用union以及位运算呢。因为在计算机中为二进制。位运算是最快速的计算方式 union C++ 中的共用体。顾名思义 就是在union 中 公用一个内存...

    老沙
  • 数据结构与算法(二)数组

    在堆中连续开辟的一段空间,每个元素占有相同大小的空间。一经开辟,即固定大小,无法改变长短。

    老沙
  • 面向对象有限元编程|自定义求解器之共轭梯度法

    共轭梯度法是方程组求解的一种迭代方法。这种方法特别适合有限元求解,因为该方法要求系数矩阵为对称正定矩阵,而有限元平衡方程的系数矩阵正好是对称正定矩阵(考虑边界条...

    fem178
  • 常见设计模式 Python 实现

    单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类 “类 (计算机科学)”)必须保证只有一个实例存在。许多时候整个系统只需要拥有一...

    Ewdager
  • Python 中的上下文管理

    当我们执行语句块前需要一些准备动作,在执行完成之后又需要执行一些收尾动作。比如:文件读写后需要关闭,数据库读写完毕后需要关闭连接,资源加锁解锁等情况。对于这种情...

    Ewdager
  • Python上下文管理器

      在Python中让自己创建的函数、类、对象支持with语句,就实现了上线文管理协议。我们经常使用with open(file, "a+") as f:这样的...

    用户1432189
  • 线性排序算法-堆排序 (2)

    在学数据结构的时候,链表、堆栈、树三种数据结构印象最深刻。当时理解有误区,堆栈被当成一种结构,可能因为堆栈有同样的特性——只关心堆顶或栈顶的元素。

    birdskyws
  • 上下文管理协议(__enter__,__exit)

    原文链接:https://www.cnblogs.com/Meanwey/p/9898673.html

    于小勇
  • HoneyTalk——我和我女朋友的专属情侣聊天器

    Arduino聊天室是一个匿名群聊应用 但是今天的应用是一对一 专属情侣聊天 话不多说 还不快来看看

    聪明的瓦肯人

扫码关注云+社区

领取腾讯云代金券