做IOS开发的人都知道,Objective-C语言中方法的调用是运行时采取绑定的,在编译过程中只声明该方法的存在。

那么我们来简单说下在运行时,类的消息传递。

在运行时,每个方法如[self methodName]向系统发送一个消息被编译器转换成: objc_msgSend( id receiver, SEL selector ,参数…)  的 C 函数调用。

在我们写代码的时候,是不需要直接使用这种写法的,此过程是编译器帮助我们转换的。但是,不需要不代表不可以,在程序运行时,我们也可以直接使用此类方法。在不定方法名或拼装方法名的时候就经常用到,如:

   SEL select = NSSelectorFromString([NSString stringWithFormat:@"parse%d:type:", p->m_wDataType]);
        if ([self respondsToSelector:select]) {
            DDLogVerbose(@"DataEngine call %@", NSStringFromSelector(select));
            ((void (*)(id, SEL, const UInt8*,EMSocketType))objc_msgSend)(self, select, data,type);
        } else {
            DDLogWarn(@"DataEngine call unkonw fun type = %d", p->m_wDataType);
        }

在 objc_msgSend 动态绑定过程是这样的

 A.首先通过第一个参数的 receiver,找到它的isa 指针,然后在 isa 指向的 Class 对象中使用第二个参数selector 查找方法;
 B.如果没有找到,就使用当前Class 对象中的新的isa 指针到上一级的父类的Class 对象中查找;
 C.当找到方法后,再依据receiver 的中的self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP 指针函数),然后传递参数,调用实现方法。
 D.假如一直找到NSObject 的Class 对象,也没有找到你调用的方法,就会报告不能识别发送消息的错误。

Objective-C运行时态消息传递--拼接方法名的更多相关文章

  1. JAVA中获取当前运行的类名,方法名,行数

    JAVA中获取当前运行的类名,方法名,行数 public static String getTraceInfo(){ StringBuffer sb = new StringBuffer(); Sta ...

  2. Java中获取运行代码的类名、方法名

    以下是案例,已运行通过 package com.hdys; /* * 1.获取当前运行代码的类名,方法名,主要是通过java.lang.StackTraceElement类 * * 2. * [1]获 ...

  3. ThinkPHP 3.2 中获取所有函数方法名,以及注释,完整可运行

    <?php namespace Home\Controller; use Common\Controller\BaseController; class AuthController exten ...

  4. .NET 中获取调用方法名

    在写记录日志功能时,需要记录日志调用方所在的模块名.命名空间名.类名以及方法名,想到使用的是反射(涉及到反射请注意性能),但具体是哪一块儿还不了解,于是搜索,整理如下: 需要添加相应的命名空间: us ...

  5. 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程

    在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...

  6. 子类重载父类的方法“parent:方法名”

    在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...

  7. PHP 获取当前类名、方法名、URL地址

      1.PHP获取当前类名.方法名  __CLASS__ 获取当前类名  __FUNCTION__ 当前函数名(confirm)  __METHOD__ 当前方法名 (bankcard::confir ...

  8. python-获取类名和方法名,动态创建类和方法及属性

    获取类名和方法名1.在函数外部获取函数名称,用.__name__获取2.在函数内部获取当前函数名称,用sys._getframe().f_code.co_name方法获取3.使用inspect模块动态 ...

  9. [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法

    using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...

随机推荐

  1. JS中的prototype(转载)

    在研究别人写的js图像处理算法时,发现其中脚本中大量使用prototype,很难读明白,就网上查了下资料发现这篇文章很易懂,就转载如下: 1 原型法设计模式 在.Net中可以使用clone()来实现原 ...

  2. 个推 Spark实践教你绕过开发那些“坑”

    Spark作为一个开源数据处理框架,它在数据计算过程中把中间数据直接缓存到内存里,能大大提高处理速度,特别是复杂的迭代计算.Spark主要包括SparkSQL,SparkStreaming,Spark ...

  3. 通过VS2010命令提示窗口创建强命名文件时报错问题

    问题描述详见图 解决方案 00000005意思是Access Denied(即拒绝访问). 原因是:Program Files(x86)目录对一般用户和未提升权限的管理员是只读的. 所以只要赋予Use ...

  4. [转] iOS ABI Function Call Guide

    source: apple ARMv6 Function Calling Conventions When functions (routines) call other functions (sub ...

  5. Linux环境进程间通信(五): 共享内存(下)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  6. 企业架构研究总结(37)——TOGAF企业连续体和工具之架构资源库及架构工具的选择

    3. 架构资源库 在一个企业,尤其是在一个大型企业中,建设一个成熟的架构往往会产生大量的工作产品.为了很好地管理和利用这些工作产品,企业需要制定一个正式的针对不同类型架构资产的分类方法,并且还需要专门 ...

  7. sed 入门

         sed 是 stream editor(流编辑器)的缩写.它能够完美配合正则表达式使用.sed命令众所周知的一个功能是文本的替换. 1. sed可以替换给定文本中的字符串.它可以配合正则表达 ...

  8. ios7上隐藏status bar

    在iOS7上 对于设置status bar 又有了点点的改变 1.对于 UIViewController 加入了动态改变 status bar style的方法 - (UIStatusBarStyle ...

  9. Google开源的Deep-Learning项目word2vec

    用中文把玩Google开源的Deep-Learning项目word2vec   google最近新开放出word2vec项目,该项目使用deep-learning技术将term表示为向量,由此计算te ...

  10. mysql 和 mongo db 语法对比

    本文描述了MySQL中的常用SQL语句在MongoDB中的写法,如果你长期使用MySQL而对MongoDB跃跃欲试,这篇简单的文章可以帮助你更快的进入角色.查询:MySQL:SELECT * FROM ...