zoukankan      html  css  js  c++  java
  • Objective-C之消息机制

    话说2014年4月编程语言排行榜中Objective-C的使用比又增加了,看来IOS和MAX OS的开发者是真给力呀。

    不过个人感觉用不了多久,IOS和Android的开发者收入就不会有那么大的差异了,因为从现在Android软件的质量上来讲已经有了质的提升。

    (扯远了,以上观点纯属虚构,如有雷同,纯属巧合)

     

    闲话少说,今儿个聊聊Objective-C的动态绑定。

    “消息结构”(messaging structure)

    说到动态绑定,就得先说一下Objective-C的“消息结构”(messaging structure)。

    "消息结构"与“函数调用”(function calling)还是有很大不同的。

    其关键不同在于:

    • 使用消息结构的语言,其运行时所应执行的代码由运行环境来决定。      
    • 使用函数调用的语言,则由编译器决定。

    再通俗点说就是:

      采用消息结构的语言,不论是否多态,总是在运行时才会去查找所要执行的方法。

       实际上,编译器设置不关心接收消息的对象是否是何种类型。接收消息的对象问题也要在运行时处理,其过程叫做“动态绑定”(dynamic binding)。

     “动态绑定”(dynamic binding)

    在解释动态绑定之前,首先看两段小代码:

     代码段1:

     1 #import <stdio.h>
     2 
     3 void A () {
     4     printf("A");
     5 }
     6 
     7 void B () {
     8     printf("B");
     9 }
    10 
    11 void callMethod (int value) {
    12     if (value == 0) {
    13         A ();
    14     } else {
    15         B ();
    16     }
    17 }

     

    代码段2:

    #import <stdio.h>
    
    void A () {
        printf("A");
    }
    
    void B () {
        printf("B");
    }
    
    void callMethod (int value) {
        void (*func)();
        if (value == 0) {
            func = A
        } else {
            func = B;
        }
        func();
    }

    下边对以上的代码段进行一下解释:

    从功能上来讲,两段代码是一样的,不多说(如果连功能都看不懂的话...咳咳...)

    主要是聊一下这两者的区别:

    • 第一段代码是所谓的“静态绑定”(static binding),也就是说,以上代码在程序的编译阶段就能决定运行时所应该调用的函数。

       此时编译器在编译代码的时候就已经知道程序中有A和B这两个函数,并且将这两个函数的地址硬编码子指令之中。

    • 第二段代码是所谓的“动态绑定”(dynamic binding),也就是说,要运行的函数,只有在运行阶段才能决定调用的是A函数还是B函数。

       此时编译器只能等到运行时才会把调用的函数地址硬编码在指令中。

     

    如何实现动态调用

     拿这段代码来举例:

      id returnValue = [object messageName:parameter];

    如果用“函数调用”的思想来读这段代码的话就是:

      调用object对象的messageName方法,并且传递参数parameter。调用此方法之后返回值为returnValue。

    但是!!!Objective-C是“消息结构”!!!

    所以正确的理解方式应该是这样:

    • returnValue是返回值,这一点与“函数调用”并没有什么区别。
    • object是消息的“接收者”(receiver),也就是我们给object对象发送了一个消息。
    • messageName,是“选择子”(selector),注意messageName并不是message。那位童鞋问那message是哪个?别着急,咱后边会说。
    • parameter是参数,与“函数调用”没有什么区别。

    前边说messageName并不是我们所理解的message,为什么这么说呢?哦~~~?

    这么说吧,如果我告诉你去北京找一个叫张三的人,那你肯定就疯了。

    但是,如果我告诉你去北京**区**街**小区**栋**室的张铁锤家的张三,是不是很容易呢?

    在“消息机制”中,messageName就相当于张三,而object就相当于balabala家的张铁锤。

    所以说,“消息”(message)并不是“选择子”(selector),而是“选择子”(selector)与“接收者”(receiver)的组合。

     

    怎样传递消息

    当编译器收到"id returnValue = [object messageName:parameter]"这条消息的时候,就会将其转换为C语言函数调用(因为Objective-C的底层调用的是C语言),调用的这个函数就是消息传递机制中的核心函数,叫objc_msgSend。

    objc_msgSend函数的原型为:void objc_msgSend(id self, SEL cmd, ...)

    • id self 代表消息的接收者
    • SEL cmd 代表选择子
    • ... 代表参数,同时也说明了这是个参数个数可变的函数。

    如果将"id returnValue = [object messageName:parameter]"转换为C语言代码的话就应该这么写:

    id returnValue = objc_megSend(object, @selector(messageName:), parameter);

    objc_megSend函数要做的就是根据接收者与选择子的类型来调用适当的方法。

    具体怎么调用的,怎么提高调用的效率,balabala,还是大家有时间自己研究一下吧。

    另外附上咱家的微信公众号的二维码,没事儿可以扫扫哈。

    有啥事儿大家可以随时留言交流。

  • 相关阅读:
    ASP.NET Forums 2.0 修改集锦(一)
    在自己的应用程序中显示Windows关于对话框
    ASP.NET Forums 2.0 本地化修改(四)
    Flash对双字节的支持问题
    DotNetNuke 2.1.2安装指南
    ASP.NET Forums 2.0 本地化修改(五) 增加页面Meta标记的keywords和description
    ASP.NET Forums 2.0 本地化修改(三)
    JavaScript利用正则表达式自己写数字判断函数
    hash表基础知识(转载)
    求子数组的最大和
  • 原文地址:https://www.cnblogs.com/studylifezy/p/3661583.html
Copyright © 2011-2022 走看看