首页 > 其他 > 详细

OC之消息基本概念

时间:2015-10-19 17:19:09      阅读:231      评论:0      收藏:0      [点我收藏+]
要说清楚消息这个话题,我们必须先来了解三个概念 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; /*父类*/
const char *name; /*类名字*/
long version; /*版本信息*/
long info; /*类信息*/
long instance_size; /*实例大小*/
struct objc_ivar_list *ivars; /*实例参数链表*/ 
struct objc_method_list **methodLists; /*方法链表*/ 
struct objc_cache *cache; /*方法缓存*/ 
struct objc_protocol_list *protocols; /*协议链表*/
};
NSObject 的 class 方法就返回这样一个指向其类结构的指针。每一个类实例对象的第一个实例变量是一个指向该对象的类结构的指针,叫做isa.
通过该指针,对象可以访问它对应的类以及相应的父类。如图一 所示: 

 技术分享

如图一所示,圆形所代表的实例对象的第一个实例变量为 isa,它指向该类的类结构 The object’s class。 而该类结构有一个指向其父类类结构的指针 superclass, 以及自身消息名称(selector)/实现地址(address) 的方法链表。 

  • 方法的含义:

注意这里所说的方法链表里面存储的是 Method 类型的。图一中 selector 就是指 Method 的

SEL, address 就是指 Method 的 IMP。 Method 在头文件 objc_class.h 中定义如下: 

typedef struct objc_method *Method;
typedef struct objc_ method 
{ 
    SEL method_name;//表示该方法的名称 
char *method_types;//该方法参数的类型
IMP method_imp; //指向该方法的具体实现的函数指针 
};

SEL 的含义:
在前面我们看到方法选标 SEL 的定义为:
typedef struct objc_selector *SEL;
它是一个指向 objc_selector 指针,表示方法的名字/签名。 

-(NSInteger)maxIn:(NSInteger)a theOther:(NSInteger)b
 {
    return (a > b) ? a : b; 
}

NSLog(@"SEL=%s", @selector(maxIn:theOther:));
输出:SEL=maxIn:theOther:
不同的类可以拥有相同的 selector,这个没有问题,因为不同类的实例对象 performSelector 相同的 selector 时,会在各自的消息选标(selector)/实现地址(address) 方法链表中根据 selector 去查找具体的 方法实现 IMP, 然后用这个方法实现去执行具体的实现代码。这是一个动态绑定的过程,在编译的时候, 我们不知道最终会执行哪一些代码,只有在执行的时候,通过 selector 去查询,我们才能确定具体的执行代码。 

IMP 的含义:
在前面我们也看到 IMP 的定义为: typedef id (*IMP)(id, SEL, ...);

根据前面 id 的定义,我们知道 id 是一个指向 objc_object 结构体的指针,该结构体只有一个成员 isa,所 以任何继承自 NSObject 的类对象都可以用 id 来指代,因为 NSObject 的第一个成员实例就是 isa。 

IMP 是一个函数指针,这个被指向的函数包含一个接收消息的对象id(self 指针), 调用方法的选标 SEL (方法名),以及不定个数的方法参数,并返回一个 id。 

NSObject 类中的 methodForSelector:方法就是这样一个获取指向方法实现 IMP 的指针, methodForSelector:返回的指针和赋值的变量类型必须完全一致,包括方法的参数类型和返回值类型。 

下面的例子展示了怎么使用指针来调用 setFilled:的方法实现: 

void (*setter)(id, SEL, BOOL); 
int i;

setter = (void(*)(id, SEL, BOOL))[target  methodForSelector:@selector(setFilled:)];

for (i = 0; i < 1000; i++)
setter(targetList[i], @selector(setFilled:), YES);
使用 methodForSelector:来避免动态绑定将减少大部分消息的开销,但是这只有在指定的消息被重复发 送很多次时才有意义 
注意,methodForSelector:是 Cocoa 运行时系统的??供的功能,而不是 Objective-C 语言本身的功能。 

 

OC之消息基本概念

原文:http://www.cnblogs.com/H7N9/p/4892300.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!