Objective-C runtime 机制

[obj foo] 等同于 obj_msgSend(obj,@selector(foo))

类的底层结构代码

struct objc_class {
 Class isa OBJC_ISA_AVAILABILITY; //isa指针
#if !__OBJC2__ Class
super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
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;

objc 在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类的方法列表以及其父类方法列表中寻找方法运行。如果在层层的寻找中均位找到方法的实现,
 就会抛出unrecognized selector sent to XXX的异常,导致程序奔溃.
 在这奔溃前,oc运行时提供了三次拯救程序的机会
 
 1、Method resolution ,动态方法解析阶段
 对应的具体方法是+(BOOL)resolveInstanceMethod:(SEL)sel 和+(BOOL)resolveClassMethod:(SEL)sel,
 当方法是实例方法时调用前者,当方法为类方法时,调用后者。这个方法设计的目的是为了给类利用 class_addMethod 添加方法的机会。
 
 2、fowarding 方法转发,备援接收者阶段
 对象的具体方法是-(id)forwardingTargetForSelector:(SEL)aSelector ,
 此时,运行时询问能否把消息转给其他接收者处理,也就是此时系统给了个将这个 SEL 转给其他对象的机会。
 
 3、 fowarding 方法转发,完整消息转发阶段
 对应方法-(void)forwardInvocation:(NSInvocation *)anInvocation,这是消息转发流程的最后一个环节。参数 anInvocation 中包含未处理消息的各种信息(selector\target\参数...)。
 在这个方法中,可以把 anInvocation 转发给多个对象,与第二步不同,第二步只能转给一个对象
 
 如果上述3个方法都没有来处理这个消息,就会进入 NSObject 的-(void)doesNotRecognizeSelector:(SEL)aSelector方法中,抛出异常

总结一下整个消息转发的流程:

代码:

#import "ViewController.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UILabel *displayLabel;
- (IBAction)buttonTest:(UIButton *)sender;
@end

@implementation ViewController

- (IBAction)buttonTest:(UIButton *)sender {
    NSLog(@"--1--");
    [self performSelector:@selector(setText:) withObject:@"hello"];
}

+(BOOL)resolveInstanceMethod:(SEL)sel
{
    NSLog(@"--2--");
    return NO;
}
//+(BOOL)resolveClassMethod:(SEL)sel
//{
//    NSLog(@"--2--");
//    return NO;
//}

-(id)forwardingTargetForSelector:(SEL)aSelector
{
    NSLog(@"--3--");
    return nil;
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSLog(@"--4--");
   NSMethodSignature *signature= [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature=[self.displayLabel methodSignatureForSelector:aSelector];
    }

    return signature;
}

-(void)forwardInvocation:(NSInvocation *)anInvocation
{
    NSLog(@"--5--");
    SEL seletor=[anInvocation selector];
    if([self.displayLabel respondsToSelector:seletor]){
        [anInvocation invokeWithTarget:self.displayLabel];
    }
}

@end

参考:

链接:iOS消息转发机制详解

链接:OC最实用的runtime总结,面试、工作你看我就足够了!

时间: 2024-10-09 22:43:17

Objective-C runtime 机制的相关文章

Objective-C的对象模型和runtime机制

内容列表 对象模型(结构定义,类对象.元类和实例对象的关系) 消息传递和转发机制 runtime系统功能理解 对象模型 结构定义 对象(Object): OC中基本构造单元 (building block),用于存储和传递数据. 可以在objc.h的文件中查找到对象结构的定义,如下所示即对象结构为Class类型的isa,而Class是 objc_class结构类型指针.objc_class即我们理解的类对象结构,其也包含一个isa类对象结构指针. 类和对象的最终实现都是一种数据结构,(subcl

iOS runtime机制 和数据库结合 使用方便开发

1 首先说一下 runtime 运行机制 对于OC 这门高级编程语言 其实在语言底层的实现 是用C语言来实现的 一个OC的类 翻译成C 语言其实就是一个结构体的类型,当然结构体是非常复杂的包括了这个类的所有信息,类的继承还是有点难度的,暂时不用考虑类的继承的问题,只要知道OC类 底层是转换成 C语言的结构体! 我们先看一下 OC 是怎样发送消息的 也就是对应C语言是如何实现函数的调用的过程! [obj makeText];   //obj 这个类发送了一个  makeText的消息 之后runt

Objective-C isa 指针 与 runtime 机制

一.isa指针 要认识什么是isa指针,我们得先明确一点: 在Objective-C中,任何类的定义都是对象.类和类的实例(对象)没有任何本质上的区别.任何对象都有isa指针. 那么什么是类呢?在xcode中用快捷键Shift+Cmd+O 打开文件objc.h 能看到类的定义: 可以看出: Class 是一个 objc_class 结构类型的指针, id是一个 objc_object 结构类型的指针. 我们再来看看 objc_class 的定义: 稍微解释一下各个参数的意思: isa:是一个Cl

ios开发新手浅谈强大的runtime机制

runtime机制,实际上是一套底层的C语言代码,里面提供了很多的C数据类型和一些功能强大的C语言函数.我们所写的OC代码,在底层都是基于runtime来实现的.所以我们可以说OC实际就是披着面向对象外衣的C语言,因为在运行时,OC代码会编译成C/C++ 来运行.runtime中有很多的C函数,有着很强大的功能,比如 : 1. 能动态类的增删改 成员变量,方法 2.IOS Swizzle 能底层动态的交换两个方法(类方法和对象方法)的实现 IOS swizzle的具体做法: 1.在分类的load

Objective-C中runtime机制的应用

Objective-C中runtime机制的应用 一.初识runtime Objective-C是一种动态语言,所谓动态语言,是在程序执行时动态的确定变量类型,执行变量类型对应的方法的.因此,在Object-C中常用字符串映射类的技巧来动态创建类对象.因为OC的动态语言特性,我们可以通过一些手段,在程序运行时动态的更改对象的变量甚至方法,这就是我们所说的runtime机制. 二.你还有什么办法操作这样的变量么? 首先,我们先来看一个例子,这里有我创建的一个MyObject类: ? 1 2 3 4

RunTime机制--原理(一)

原文地址:http://my.oschina.net/panyong/blog/297640 对于runtime机制,在网上找到的资料大概就是怎么去用这些东西,以及查看runtime.h头文件中的实现,当然这确实是一种很好的学习方法,但是,其实我们还是不会知道runtime底层编译成C++语言之后做了什么? 查到一个大牛给资料,顿时对runtime有了一定认识! 我们随便写一个小程序,代码如下: person类头文件如下, <!-- lang: cpp --> #import <Foun

我理解的iOS中的RunTime机制(1)

一.首先我们要先知道object-c是一门编译型.动态语言(这里强调下oc是静态类型语言),这在开发语言中是并多见的,一般的动态语言多为解释性语言.oc之所以能够做到即使编译型语言,又是动态语言.就是得益于RunTime机制. 由于本文主要讲解的是RunTime机制,所以语言类型不做过多描述,之后可以另写一篇语言类型的介绍. 二.这里主要讲解RunTime如何使用,其中主要的知识点如下: 1.class_copyPropertyList  获取一份拷贝的成员列表数组 2.property_get

Swift是否和OC一样有runtime机制

OC语言最大的特性无疑是其的动态性,可以利用OC的动态性能够获得一个类的方法和属性,从而实现灵活的程序,但Swift是否也包含了runtime机制呢? 参考链接:http://mp.weixin.qq.com /s?__biz=MzA3ODg4MDk0Ng==&mid=403153173&idx=1&sn=c631f95b28a0eb4b842a9494e43a30e5&scene=23&srcid=0331ZwO8t6uWiBON621r1GhC#rd 下面我们将

iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行

一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头文件#import <objc/runtime.h> 通过这三个方法动态的绑定属性 OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy poli

Objective-C Runtime机制详解

Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时做的事放到了运行时来处理.同时OC也是一门简单的语言,很大一部分是C的内容,只是在语言层面上加了关键字和语法,真正让OC强大的是它的运行时,它很小却很强大,其中核心是消息分发.这种动态语言的优势在于:我们写代码时更加灵活,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现. 这种特性意味着OC不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于OC来说,这个运行时系统就像一个操作系统一样.这个运行时系