iOS Runtime详解之SEL,Class,id,IMP,_cmd,isa,method,Ivar
2017-12-14 11:30
573 查看
原文:http://blog.csdn.net/hello_hwc?viewmode=list
前言:写了这么久的iOS博客,也是时候写写Rumtime的东西了,实际开发中用到的比较多的场景
动态改变方法的执行体
Method Swizzling
NSSelectorFromString,NSClassFromString…
动态添加属性(主要是类别)
动态遍历属性和方法,动态为类添加方法
但是,基本的概念很重要,计划Runtime这个系列计划几篇文章
讲讲一些基本概念(本文),例如SEL,Class,id,IMP等等
详解iOS 中消息的传递机制,以及消息转发机制,内存分配,类对象,类元对象
Method Swizzling
其他常见实际应用
Objective C语言把能在运行期做的事情就推迟到运行期再决定。这就意味着,Objective C不仅需要一个编译器,而且需要一个运行期环境。这个运行期环境就是Runtime。
最直接的例子就是方法调用
这样的一个OC方法
会被编译成
这里,先记着receiver就是接受消息的对象,selector是执行消息的函数体名称,是个C的字符串。而不是像其他语言一样,直接编译成一个指向函数体的指针。
那么,在运行的时候,如何通过objc_msgSend(receiver, selector)找到实际的函数体呢?
That is Runtime!
记得最开始接触Runtime的时候,感觉很乱,看得我最后都迷糊了,最后想了想,主要还是一些基本概念不清楚,搞不清楚这些名词是几乎不可能深入理解和应用Runtime的。
所以,我讲解Runtime的方式是,先搞清楚一些基本的关键词的底层定义,然后讲解消息处理以及转发机制,最后讲解示例。
objc_selector
透明的数据结构,可以理解为C String
SEL
源代码定义
2
也就是说,SEL是指向一个C String的指针。
id - 指向一个类的实例对象
底层代码定义
其中
objc_object的底层定义
2
3
可以看到,objc_object中,只是保存了一个Class类型的isa。这里看不懂不要怕,先记着,对象中就是保存了一个指向Objective C中对应类的指针。
Class - 指向Objective C类对象(objc_class)的一个指针
底层定义
objc_class
底层定义
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以看到,这就是类对象结构体的定义,细心的同学可能发现了类对象里仍然有一个指针Class isa,先记着,这个isa指向的是类元对象。这个我会在下一篇文章里详细阐述
IMP-指向实际执行函数体的函数指针
2
3
4
5
可以看到,这个函数体前两个参数是 id(消息接受者,也就是对象),以及SEL(方法的名字)
method - 指向Objective C中的方法的指针
其中
2
3
4
5
6
SEL 类型的一个变量,Objective C的函数的前两个隐藏参数为self 和 _cmd
ivar - objective C中的实例变量
2
可以看到变量的内存模型
2
3
4
5
6
7
8
前言:写了这么久的iOS博客,也是时候写写Rumtime的东西了,实际开发中用到的比较多的场景
动态改变方法的执行体
Method Swizzling
NSSelectorFromString,NSClassFromString…
动态添加属性(主要是类别)
动态遍历属性和方法,动态为类添加方法
但是,基本的概念很重要,计划Runtime这个系列计划几篇文章
讲讲一些基本概念(本文),例如SEL,Class,id,IMP等等
详解iOS 中消息的传递机制,以及消息转发机制,内存分配,类对象,类元对象
Method Swizzling
其他常见实际应用
什么是Runtime?
Objective C语言把能在运行期做的事情就推迟到运行期再决定。这就意味着,Objective C不仅需要一个编译器,而且需要一个运行期环境。这个运行期环境就是Runtime。最直接的例子就是方法调用
这样的一个OC方法
[receiver message]1
会被编译成
objc_msgSend(receiver, selector)1
这里,先记着receiver就是接受消息的对象,selector是执行消息的函数体名称,是个C的字符串。而不是像其他语言一样,直接编译成一个指向函数体的指针。
那么,在运行的时候,如何通过objc_msgSend(receiver, selector)找到实际的函数体呢?
That is Runtime!
为什么要写这样一篇基础的文章?
记得最开始接触Runtime的时候,感觉很乱,看得我最后都迷糊了,最后想了想,主要还是一些基本概念不清楚,搞不清楚这些名词是几乎不可能深入理解和应用Runtime的。所以,我讲解Runtime的方式是,先搞清楚一些基本的关键词的底层定义,然后讲解消息处理以及转发机制,最后讲解示例。
SEL/objc_selector
objc_selector 透明的数据结构,可以理解为C String
SEL
源代码定义
typedef struct objc_selector *SEL;1
2
也就是说,SEL是指向一个C String的指针。
id/objc_object
id - 指向一个类的实例对象 底层代码定义
typedef struct objc_object *id;1
其中
objc_object的底层定义
struct objc_object { Class isa OBJC_ISA_AVAILABILITY; };1
2
3
可以看到,objc_object中,只是保存了一个Class类型的isa。这里看不懂不要怕,先记着,对象中就是保存了一个指向Objective C中对应类的指针。
Class/objc_class
Class - 指向Objective C类对象(objc_class)的一个指针 底层定义
typedef struct objc_class *Class;1
objc_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; /* Use `Class` instead of `struct objc_class *` */1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以看到,这就是类对象结构体的定义,细心的同学可能发现了类对象里仍然有一个指针Class isa,先记着,这个isa指向的是类元对象。这个我会在下一篇文章里详细阐述
IMP
IMP-指向实际执行函数体的函数指针#if !OBJC_OLD_DISPATCH_PROTOTYPES typedef void (*IMP)(void /* id, SEL, ... */ ); #else typedef id (*IMP)(id, SEL, ...); #endif1
2
3
4
5
可以看到,这个函数体前两个参数是 id(消息接受者,也就是对象),以及SEL(方法的名字)
method/objc_method
method - 指向Objective C中的方法的指针typedef struct objc_method *Method;1
其中
struct objc_method { SEL method_name OBJC2_UNAVAILABLE; char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; } OBJC2_UNAVAILABLE;1
2
3
4
5
6
_cmd
SEL 类型的一个变量,Objective C的函数的前两个隐藏参数为self 和 _cmd
Ivar
ivar - objective C中的实例变量typedef struct objc_ivar *Ivar;1
2
可以看到变量的内存模型
struct objc_ivar { char *ivar_name OBJC2_UNAVAILABLE; char *ivar_type OBJC2_UNAVAILABLE; int ivar_offset OBJC2_UNAVAILABLE; #ifdef __LP64__ int space OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE;1
2
3
4
5
6
7
8
相关文章推荐
- iOS Runtime详解之SEL,Class,id,IMP,_cmd,isa,method,Ivar
- iOS开发使用 runtime 方法中的 class_copyIvarList,class_copyMethodList 方法时导致内存泄漏问题
- 《Objective-C Runtime分析(二)-Class,Method,SEL,IMP》
- what is the SEL,id and IMP,Class ,Method?
- id,SEL,Nil,nil,IMP,Method,Class类型
- id,SEL,Nil,nil,IMP,Method,Class类型
- 【Android基础学IOS开发】BOOL SEL IMP isa
- Runtime关于SEL、IMP、Method、isa、Class
- objc/runtime中SEL、IMP和method动态定义
- objc/runtime中SEL、IMP和method动态定义
- objc/runtime中SEL、IMP和method动态定义
- IOS Object C id,class,sel,bool
- Objective-C-- id、nil、Nil、SEL、IMP、Method、Class
- runtime运行时 isa指针 SEL方法选择器 IMP函数指针 Method方法 runtime消息机制 runtime的使用
- iOS---runtime之IMP指针,isa指针
- Method Swizzle黑魔法,修改 ios 系统类库方法 SEL IMP
- iOS 开发 深入浅出Runtime运行时之方法动态处理(Dynamic Method Resolution)详解
- iOS:iOS8开发(二)~storyboard中autolayout和size class的使用详解
- Runtime方法的使用—Method、Ivar、Property篇
- IllegalArgumentException in class: my.models.base.BaseVo, getter method of property: id