iOS底层原理总结 - OC方法的本质

**上一篇**我们讲到iOS对象的底层的本质是结构体!!!这一篇我们来看看我们通过clang -rewrite-objc main.m -o mian.cpp编译的对象调用方法底层

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        LGPerson *p = ((LGPerson *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("LGPerson"), sel_registerName("new"));
        ((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("run"));
    }
    return 0;
}

可以看出在我们进行LGPerson初始化的时候,我们都知道会调用alloc,init.我这里为了简单只调用’new’.但是底层不是像我们利用[]调用的,而是调用了一个函数objc_msgSend这就是我们消息发送的方法,因为考虑的参数我们进行了前面的强转.如果有一定C功底就知道objc_msgSend就是发送消息,我们在断点调试ViewDidLoad的时候,发现能打印self,_cmd这就是我们的消息底层默认的两个参数id,SEL

  • 一个是消息接受者
  • 一个是消息编号
    我们还可以在objc_msgSend末尾继续加参数,但是考虑到编译参数问题,我们需要关闭严格核查

关闭严格核查

通过SEL能找到函数实现,底层是依赖一个IMP的函数指针
就会找我们具体的函数实现
我们模拟是不是也可不断发送消息,模拟四种消息发送

LGStudent *s = [LGStudent new];
[s run];
// 方法调用底层编译
// 方法的本质: 消息 : 消息接受者 消息编号 ....参数 (消息体)
objc_msgSend(s, sel_registerName("run"));
// 类方法编译底层
[LGStudent walk];
objc_msgSend(objc_getClass("LGStudent"), sel_registerName("walk"));

// 向父类发消息(对象方法)
struct objc_super mySuper;
mySuper.receiver = s;
mySuper.super_class = class_getSuperclass([s class]);
objc_msgSendSuper(&mySuper, @selector(run));

//向父类发消息(类方法)
struct objc_super myClassSuper;
myClassSuper.receiver = [s class];
myClassSuper.super_class = class_getSuperclass(object_getClass([s class]));
objc_msgSendSuper(&myClassSuper, sel_registerName("walk"));

猜你喜欢

转载自blog.csdn.net/qq_42792413/article/details/85014324