首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

iOS消息转发机制(1)

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

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