话说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:

 #import <stdio.h>

 void A () {
printf("A");
} void B () {
printf("B");
} void callMethod (int value) {
if (value == ) {
A ();
} else {
B ();
}
}

代码段2:

#import <stdio.h>

void A () {
printf("A");
} void B () {
printf("B");
} void callMethod (int value) {
void (*func)();
if (value == ) {
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,还是大家有时间自己研究一下吧。

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

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

Objective-C之消息机制的更多相关文章

  1. iOS开发系列--通知与消息机制

    概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知机制就可以告诉用户此时发生的事情.iOS中通知机制又叫消息机制,其包括两类:一类是本地 ...

  2. Android消息传递之Handler消息机制

    前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...

  3. Windows消息机制

    Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...

  4. OSG消息机制之事件处理概述

    OSG的消息机制包括好多个头文件预定义及多个类. 首先,消息接收相关的类当属osgGA::GUIEventHandler和osgGA::GUIEventAdapter这两个类了.前者处理OSG程序与用 ...

  5. [转]runtime 消息机制

    原文地址:http://www.jianshu.com/p/f6300eb3ec3d 一.关于runtime 之前在项目中有遇到过用runtime解决改变全局字体的问题,所以再一次感受到了runtim ...

  6. IOS 消息机制(NSNotificationCenter)

    消息机制 NSNotificationCenter 一直都在频繁使用,但是却对其原理不是十分了解.今天就花些时间,把消息机制原理重头到尾好好过一遍. iOS 提供了一种 "同步的" ...

  7. Android之消息机制Handler,Looper,Message解析

    PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...

  8. Objective-C总Runtime的那点事儿(一)消息机制

    最近在找工作,Objective-C中的Runtime是经常被问到的一个问题,几乎是面试大公司必问的一个问题.当然还有一些其他问题也几乎必问,例 如:RunLoop,Block,内存管理等.其他的问题 ...

  9. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  10. 【温故Delphi】之VCL消息机制小结

    TObject消息分派 procedure Dispatch(var Message); virtual; #负责分派消息到特定VCL组件的事件处理函数 procedure DefaultHandle ...

随机推荐

  1. WPF 视图分组排序

    视图分组排序 效果: 实现步骤: 第一步:为分组做一个标题头,就是效果图中的浅蓝色部分: <DataGrid.GroupStyle>标签部分: <DataGrid x:Name=&q ...

  2. JavaScript 踩坑心得— 为了高速(下)

    一.前言 本文的上一篇 JavaScript 踩坑心得- 为了高速(上) 主要和大家分享的是 JavaScript 使用过程中的基本原则以及编写过程中的心得分享,本文主要和大家聊聊在各个使用场景下的 ...

  3. HDU 1422 重温世界杯(DP)

    点我看题目 题意 : 中文题不详述. 思路 : 根据题目描述及样例可以看出来,如果你第一个城市选的是生活费减花费大于等于0的时候才可以,最好是多余的,这样接下来的就算是花超了(一定限度内的花超),也可 ...

  4. UR #13 Yist

    第一次打UR,打了一个半小时就弃疗了QAQ 这是我唯一一道考试的时候做出来的题目,其他两道连暴力都懒得写了 很容易发现对于每个要删除的点 我们找到左边第一个比他小的不用删除的点,右边第一个比他小的不用 ...

  5. 关于Application.Lock和Lock(obj)

    http://www.cnblogs.com/yeagen/archive/2012/03/01/2375610.html 1.Application.Lock和Application.UnLock一 ...

  6. Java泛型:泛型类、泛型接口和泛型方法

    根据<Java编程思想 (第4版)>中的描述,泛型出现的动机在于: 有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一. ...

  7. RxJava学习( 二)

    1) Scheduler 的 API (一) 在RxJava 中,Scheduler ——调度器,相当于线程控制器,RxJava 通过它来指定每一段代码应该运行在什么样的线程.RxJava 已经内置了 ...

  8. knowledge about apache

    http://wenku.baidu.com/link?url=6O51BQJdtFRFWDGszKfN3aK7IY92QTCpuc7miBhRLazXvxL5gXb18B_TqIdi3EruX1o_ ...

  9. python学习笔记七--数据操作符

    一.Python表达式操作符及程序:

  10. JavaScript DOM高级程序设计1.3-常见陷阱--我要坚持到底!

    区分大小写 单引号双引号 大多数开发人员选择用单引号,因为XTHML要求所有XHTML的属性都必须使用双引号 var html='<h2 class="a">A lis ...