Board logo

标题: iOS消息转发机制(1) [打印本页]

作者: look_w    时间: 2019-2-19 17:25     标题: iOS消息转发机制(1)


函数的调用方式

Objective-C是C语言的超集,C语言的函数调用方式是“静态绑定的”,也就是说在编译的时候就知道运行时要调用什么函数,如果调用一个未声明的函数,编译期间就会报错。

    void printGoodMorning(){
        printf("good morning,huang");
    }
     
    void printGoodAfternoon(){
        prinf("good afternoon,huang");
    }
     
    void helloHuang(int time){
        if(time > 6 && time < 12){
            printGoodMorning();
        }else if(time < 18){
            printGoodAfternoon();
        }else{
            printHelloAllTheTime();//error here
        }
    }

但是如果我们把上面这段代码改写一下,如下

    void printGoodMorning(){
        printf("good morning,huang");
    }
     
    void printGoodAfternoon(){
        prinf("good afternoon,huang");
    }
     
    void helloHuang(int time){
        void (*hello)();
        if(time > 6 && time < 12){
            hello = printGoodMorning;
        }else if(time < 18){
            hello = printGoodAfternoon;
        }
        
        hello()
    }
     

你会发现只有当程序运行起来之后,才能知道要执行哪个函数,这就得使用“动态绑定”的概念了

Objective-C是使用传递消息的机制来调用函数,这就会使用到动态绑定的机制在运行期来决定到底调用哪个方法,甚至我们可以在运行时改变对象调用的方法。

对象发送消息大概是这样的:

id returnType = [object messageName:parameter];

编译器会转化为我们断点堆栈中经常能看到的下面这样的C函数:

void objc_msgSend(id self, SEL cmd,...)

这是个参数可以变化的函数,第一个参数代表了消息的接收者,第二个参数是所需要执行的方法名,后面是消息的参数。

objc_msgSend是如何依据消息的接收者和方法名找到合适的方法呢?

首先,需要在接收者所属的类中的方法列表中去查找这个方法,找到了直接调用,没找到则一级一级便利去基类的方法列表,直到NSObject。如果没找到,那么就会触发“消息转发”机制。

消息转发机制如果处理妥当,那么这条消息则能正常处理,如果处理不善,或者根本没处理,那么就会看到我们常看到的崩溃:

-[xxxobject xxxfunc]: unrecognized selector sent to instance 0xxx

简单的解决方案就是,去对应的类添加对应的方法就行了。但是现在我们要提到的是,怎么动态的使用消息转发来处理这个问题。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0