我们知道Objective-C 中的方法调用是在运行时才去绑定的。
进一步看,编译器会把对象消息发送 [xxx method] 转换为 objc_msgSend( id receiver, SEL selector ,参数…) 的 C 函数调用。
在我们写代码的时候,是不需要直接使用这种写法的,此过程是编译器帮助我们转换的。
在 objc_msgSend 动态绑定过程是这样的
A.首先通过第一个参数的 receiver,找到它的isa 指针,然后在 isa 指向的 Class 对象中使用第二个参数selector 查找方法;
B.如果没有找到,就使用当前Class 对象中的新的isa 指针到上一级的父类的Class 对象中查找;
C.当找到方法后,再依据receiver 的中的self 指针找到当前的对象,调用当前对象的具体实现的方法(IMP 指针函数),然后传递参数,调用实现方法。
D.假如一直找到NSObject 的Class 对象,也没有找到你调用的方法,就会报告不能识别发送消息的错误。
==============================================================================================================================
下面文章是引用:http://www.cppblog.com/kesalin/archive/2011/08/15/objc_message.html
深入浅出ObjC之消息
在入门级别的ObjC 教程中,我们常对从C++或Java 或其他面向对象语言转过来的程序员说,ObjC 中的方法调用(ObjC中的术语为消息)跟其他语言中的方法调用差不多,只是形式有些不同而已。
譬如C++ 中的:
Bird * aBird = new Bird(); aBird->fly(); |
在ObjC 中则如下:
Bird * aBird = [[Bird alloc] init]; [aBird fly]; |
乍看起来,好像只是书写形式不同而已,实则差异大矣。C++中的方法调用可能是动态的,也可能是静态的;而ObjC中的消息都为动态的。下文将详细介绍为什么是动态的,以及编译器在这背后做了些什么事情。
要说清楚消息这个话题,我们必须先来了解三个概念Class, SEL, IMP,它们在objc/objc.h 中定义:
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
typedef struct objc_selector *SEL;
typedef id (*IMP)(id, SEL, ...);
Class 的含义
Class 被定义为一个指向 objc_class的结构体指针,这个结构体表示每一个类的类结构。而 objc_class 在objc/objc_class.h中定义如下:
struct objc_class {
struct objc_class super_class; /*父类*/ //此处有错误 应该是 struct objc_class * super_class;
const char *name; /*类名字*/
long version;