iOS Runtime详解(消息机制,类元对象,缓存机制,消息转发)

原创Blog,转载请注明出处
http://blog.csdn.net/hello_hwc?viewmode=list
我的stackoverflow

profile for Leo on Stack Exchange, a network of free, community-driven Q&A sites


前言:之前一篇文章里,我详细的讲解了一些基本关键词以及基本概念,这里再简要列出来,以防有些同学看不懂。

  • SEL 方法的名字,可以理解为字符串指针类型
  • id 指向一个类的实例对象
  • isa 每个类的示例对象都保存的指针,指向类对象
  • Class 指向类对象
  • _cmd 每个OC方法都具有的参数

    但是, 我仍然推荐先看一下前一篇文章


什么是Runtime?

Objective C语言把能在运行期做的事情就推迟到运行期再决定。这就意味着,Objective C不仅需要一个编译器,而且需要一个运行期环境。这个运行期环境就是Runtime。

Runtime是用C和汇编写的,并且它是开源的。所有的Apple开源代码都可以在http://www.opensource.apple.com上找到。


Objective C中的实例方法

在OC中,方法调用称为向对象发送消息,为什么这么叫呢?我们先看个例子

[receiver message]

那么,[receiver message]编译后是什么呢?

编译后是这个样子的

objc_msgSend(receiver, selector)

我们看看这个方法的文档

id objc_msgSend(id self, SEL op, ...)

参数

  • self 消息的接收者
  • op 消息的selector,一个C的字符串用来定位
  • … 消息传入参数的数组

Runtime如何找到实例方法执行体?

上文提到了,一个OC方法被编译成objc_msgSend,那么,Runtime如何找到方法的执行体呢?

因为OC中存在一种对象叫做类对象(Class Object),类对象中保存了方法的列表,superClass等信息。

类对象的定义

typedef struct objc_class *Class;

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

可以看到这一行

    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;

那么,OC的实例对象又是如何找到类对象呢?从上文的第一部分,我们可以看到,objc_msgSend这个C函数输入参数包括,id类型的self,SEL类型的_cmd,以及参数列表。很直观,id类型中一定存在一个可以找到类对象的指针。我们来看看id定义

typedef struct objc_object *id;
struct objc_object {
   
    Class isa  OBJC_ISA_AVAILABILITY;
}

现在很清楚了,实例对象通过isa找到类对象。
我们知道了

  • OC的对象通过isa找到类对象
  • 类对象查找自己存储的方法列表来找到对应的方法执行体
  • 方法执行体执行具体的代码,并返回值给调用者。

那么,实际的方法执行体(Method)到底是什么东西?
看看Method的定义

struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
} 

Method保存了

  1. 方法的名字
  2. 方法的类型(参数列表)
  3. 方法的具体实现,由IMP指向
    其中IMP的定义
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
#else
typedef id (*IMP)(id, SEL, ...); 
#endif

我们来看一个例子,
定义一个

@interface CustomObject : NSObject
-(NSString *)returnMeHelloWorld;
@end
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值