消息转发及super

2019-09-28 13:20:57 浏览数 (1)

消息发送
动态解析

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

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

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

super

super 底层原理

代码语言:javascript复制
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")));
复制代码

精简后代码

代码语言:javascript复制
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的注释

代码语言:javascript复制
/**
 * 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的实现

0 人点赞