iOS运行时(runtime)探究一:重要概念
来源:互联网 发布:股票数据统计 编辑:程序博客网 时间:2024/06/01 22:49
iOS运行时简介
因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石。
iOS运行时的一些概念
1.类:Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。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; // 类的版本信息,默认为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;
2.实例对象:既是objc_object表示的一个类的实例的结构体,它的定义如下
struct objc_object { Class isa OBJC_ISA_AVAILABILITY;};typedef struct objc_object *id;
3.元类(Meta Class):meta-class是一个类对象的类。它存储着一个类的所有类方法。每个类都会有一个单独的meta-class。
4.方法调用过程:首先在本类中查找,如果没有就向父类中查找,然后响应该方法,最后把该方法添加到cache列表中,以后再调用该方法,直接从cache中取出相应的方法调用。
5.实例对象的isa指针指向对象所属类,类的isa指针指向元类,元类的isa指针指向根元类(根类的元类),根元类的isa指正指向自身。类的superclass指针指向父类,根类的superclass指针指向nil,根元类的superclass指针指向根类。如下图所示:
void testClass(id self, SEL _cmd){ NSObject *object = [[NSObject alloc] init]; NSLog(@"NSObject实例:%@, 地址:%p", object, object); NSLog(@"NSObject类名:%@ 地址:%p,NSObject父类名:%@ 地址:%p", [object class], [object class], [object superclass], [object superclass]); NSLog(@"MyObject实例:%@,%p", self, self); NSLog(@"MyObject类名:%@ 地址:%p,MyObject父类名:%@ 地址:%p", [self class], [self class], [self superclass], [self superclass]); Class currentClass; Class superClass = [self class]; do { currentClass = superClass; superClass = class_getSuperclass(currentClass); NSLog(@"当前类:%@ 地址:%p, 父类:%@ 地址:%p", currentClass, currentClass, superClass, superClass); } while (superClass != NULL); Class isaClass = [self class]; currentClass = NULL; do { currentClass = isaClass; isaClass = object_getClass(currentClass); NSLog(@"当前类:%@ 地址:%p,isa指针指向的类:%@ 地址:%p", currentClass, currentClass, isaClass, isaClass); } while (!(currentClass == isaClass));}- (void)createClass{ //创建一个类,注意名称一定不能是已经存在的类 Class myObjectClass = objc_allocateClassPair([NSObject class], "MyObject", 0); //向类中添加一个方法 class_addMethod(myObjectClass, @selector(testClass), (IMP)testClass, "v@:"); //注册类,注册后方能使用该类 objc_registerClassPair(myObjectClass); id myObject = [[myObjectClass alloc] init]; [myObject performSelector:@selector(testClass)];}
打印如下:
6.super:super与self不同。self是类的一个隐藏参数,每个方法的实现的第一个参数即为self。而super并不是隐藏参数,它实际上只是一个”编译器标示符”,它负责告诉编译器,当调用viewDidLoad方法时,去调用父类的方法,而不是本类中的方法。而它实际上与self指向的是相同的消息接收者。
super的定义:
struct objc_super { id receiver;//即消息的实际接收者 Class superClass;//指针当前类的父类 };
例证:
- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"self:%@ super:%@", self, super.class);}
打印如下:
7.SEL:SEL又叫选择器,是表示一个方法的selector的指针,本质上,SEL只是一个指向方法的指针(准确的说,只是一个根据方法名hash化了的KEY值,能唯一代表一个方法),它的存在只是为了加快方法的查询速度。其定义如下:
typedef struct objc_selector *SEL;
8.IMP:IMP实际上是一个函数指针,指向方法实现的首地址。SEL就是为了查找方法的最终实现IMP的。由于每个方法对应唯一的SEL,因此我们可以通过SEL方便快速准确地获得它所对应的IMP,查找过程将在下面讨论。取得IMP后,我们就获得了执行这个方法代码的入口点,此时,我们就可以像调用普通的C语言函数一样来使用这个函数指针了。其定义如下:
id (*IMP)(id, SEL, ...)
9.Method:既是objc_method表示的一个结构体,该结构体中包含一个SEL和IMP,实际上相当于在SEL和IMP之间作了一个映射。有了SEL,我们便可以找到对应的IMP,从而调用方法的实现代码。Method用于表示类定义中的方法,则定义如下:
typedef struct objc_method *Method;struct objc_method { SEL method_name OBJC2_UNAVAILABLE; // 方法名 char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; // 方法实现}
- iOS运行时(runtime)探究一:重要概念
- iOS运行时(runtime)探究二:主要函数
- iOS运行时(runtime)探究三:消息转发
- iOS运行时(runtime)探究四:实际运用
- OC运行时Runtime探究
- iOS 运行时(runtime)
- iOS运行时 runtime
- iOS runtime 运行时
- IOS runtime运行时
- iOS--RunTime运行时
- iOS runtime运行时
- IOS 运行时(runtime)机制
- iOS之运行时(Runtime)
- IOS Runtime(一)
- iOS Runtime(一)
- iOS runtime ~ 重要类型
- iOS运行时(Runtime)总结
- iOS RunTime 运行时 介绍
- MongoDB 数据导出mongoexport(可导出为txt或csv)
- MongoDB实现复制集
- ABAP SEARCH 搜索指定字符串
- Intellij Idea,webstorm,phpstorm 在线激活License server
- 【Java并发编程】之十二:线程间通信中notifyAll造成的早期通知问题(含代码)(r)
- iOS运行时(runtime)探究一:重要概念
- Linux命令模式下执行命令基本操作
- AIDL的简单使用
- jquery 小技巧
- Linux下MongoDB安装和配置详解(一)
- substr函数使用
- 【Java并发编程】之十三:生产者—消费者模型(含代码)(r)
- 二值图像连通域标记算法与代码
- Mac OSX 无共享的密钥情况下连接基于L2TP协议的VPN