欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

iOS开发之Objective-c的Runtime理解指南,

来源: 开发者 投稿于  被查看 25390 次 评论:11

iOS开发之Objective-c的Runtime理解指南,


目录
  • 一、Runtime
    • 1、概念:
    • 2、特性:编写的代码具备有运行时、动态特性,从而衍生出 以下4、5
    • 3、原理:Runtimer在Object-c的使用 程序在三个不同的层次上与运行时系统交互:
    • 4、作用:
    • 5、典型事例:
    • 6、Objc-msgSend所做的事情
    • 7、消息传递的关键要素
    • 8、Msg_sender机制:先查询本类是否又该方法的实现--->如果没有逐级找父类,还有一个快速映射表(提高性能)---> 匹配方法 ---> 设置一个执行者---> 消息转发 ---> 没有实现方法
      • resolveInstanceMethod
      • forwardingTargetForSelector
      • methodSignatureForSelector
      • forwardInvocation
  • 二、运行时常用的API:
    • objc_*
      • class_*
        • objcet_*
          • method_*
            • property_*
              • protocol_*
                • ivar_*
                  • sel_*
                    • imp_*

                    一、Runtime

                    1、概念:

                    概念:Runtime是Objective-c语言动态的核心,即运行时。在面向对象的基础上增加了动态运行,达到很多在编译时确定方法推迟到了运行时,从而达到动态修改、确定、交换。。。属性及方法

                    作用: 这给程序员写代码带来很大的灵活性,比如说你可以把消息转发给你想要的对象,或者随意交换一个方法的实现之类的!多态 kvo kvc 获得属性方法 添加属性方法

                    核心: 另外 Runtime进行消息解析和转发,动态调用过程!

                    只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。

                    2、特性:编写的代码具备有运行时、动态特性,从而衍生出 以下4、5

                    3、原理:Runtimer在Object-c的使用 程序在三个不同的层次上与运行时系统交互:

                    (1)通过Object-c源代码进行交互

                    (2)通过NSObject类中定义的方法交互

                    (3)通过直接调用运行时函数

                    4、作用:

                    (1)在程序运行过程中,动态的创建类,动态添加、修改这个类的属性的方法

                    (2)遍历一个类中的所有成员变量、属性、以及所有方法

                    (3)消息传递、转发

                    5、典型事例:

                    (1)给系统分类添加属性、方法

                    (2)方法交换

                    (3)获取对象的属性、私有属性

                    (4)字典转换模型

                    (5)KVO、KVC

                    (6)(NSClassFromString class)字符串

                    (7)block

                    (8)类的自我检测

                    6、Objc-msgSend所做的事情

                    (1)找到方法的实现,由于通过单独的类以不同方式创建相同的方法,因此这个方法的实现的确定取决于接收消息的类的对象,也既是说多个实例类对戏那个可以创建同样的方法,每个实例对象中该方法都是独立存在的

                    (2)调用该方法实现,将接收消息类指针,以及该方法的参数传递给这个类

                    (3)最后将过程的返回值作为自己的返回值传递

                    7、消息传递的关键要素

                    (1)指向superclass指针

                    (2)会有一个SEL跟方法实现的

                    8、Msg_sender机制:先查询本类是否又该方法的实现--->如果没有逐级找父类,还有一个快速映射表(提高性能)---> 匹配方法 ---> 设置一个执行者---> 消息转发 ---> 没有实现方法

                    1. re solveInstanceMethod  决策实力,动态方法解析
                    2. forwardingTargetForSelector 转寄Target ,设置一个执行者 备用接收者
                    3. MethodSignatureForSelector 方法签名,
                    4. forwardInvocation 转寄求助,消息重定向
                    5. doesNotRecognizeSelector 没有找到方法 崩溃

                    先调用resolveInstanceMethod,如果在这里使用runtime动态添加对应的方法,并且返回YES,消息就找到了响应的对象,并将这个新增的方法添加到类的方法缓存列表 如果上面的方法返回NO的话,对象会调用forwardingTargetForSelector方法,以实现消息的转发,让其他对象来处理这个消息。 如果以上两个方法都没有做处理,那么对象会执行最后一个方法methodSignatureForSelector,提供一个有效的方法签名。若提供了有效的方法签名,程序会通过forwardInvocation方法执行签名。若没有提供方法签名,触发doesNotRecognizeSelector方法,触发崩溃。

                    resolveInstanceMethod

                    resolveInstanceMethod是Objective-C语言中一种动态方法解析的接口,是得我们可以在运行时动态的为一个selector提供实现。我们只需要实现 +resolveInstanceMethod和+resolveClassMethod方法,并在其中为指定的selector提供实现即可(通过调用运行时函数class_addMethod来添加)。这两个方法都是NSObject中的类方法,其原型为:

                    + (BOOL)resolveClassMethod:(SEL)name;
                    + (BOOL)resolveInstanceMethod:(SEL)name;

                    参数那么是需要被动态解析的selector;如果在该函数中为指定的selector提供实现,无论返回YES还是NO,编译运行都是正确的。如果在该函数内并没有真正的为selector提供实现,如果返回YES,运行会crash。其原理很简单,因为当前类既没有为selector提供实现,又没有实现消息转发,自然会crash。

                    forwardingTargetForSelector

                    forwardingTargetForSelector是Objective-C语言中消息快速重定向的函数。开发者可以在派生类中对其进行重载,从而将无法处理的selector转发给另一个对象。

                    methodSignatureForSelector

                    methodSigntureForSelector的作用在在于为另一个类实现的消息创建一个有效的方法签名。如果没有实现有效的方法签名,程序就会崩溃

                    forwardInvocation

                    在返回有效的方法签名的情况下,当前对象则会调用forwardInvocation方法,以完成消息的最终传递。

                    1、动态解析的一个例子

                    2、备用接受者

                    3.重签名

                    二、运行时常用的API:

                    objc_*

                    objc_系列函数关注于宏观使用,如类与协议的空间分配,注册,注销等操作

                    // 1.objc_xxx 系列函数
                    // 函数名称     函数作用
                    objc_getClass     获取Class对象
                    objc_getMetaClass     获取MetaClass对象
                    objc_allocateClassPair     分配空间,创建类(仅在 创建之后,注册之前 能够添加成员变量)
                    objc_registerClassPair     注册一个类(注册后方可使用该类创建对象)
                    objc_disposeClassPair     注销某个类
                    objc_allocateProtocol     开辟空间创建协议
                    objc_registerProtocol     注册一个协议
                    objc_constructInstance     构造一个实例对象(ARC下无效)
                    objc_destructInstance     析构一个实例对象(ARC下无效)
                    objc_setAssociatedObject     为实例对象关联对象
                    objc_getAssociatedObje*ct     获取实例对象的关联对象
                    objc_removeAssociatedObjects     清空实例对象的所有关联对象

                    class_*

                    class_系列函数关注于类的内部,如实例变量,属性,方法,协议等相关问题

                    // 2.class_xxx 系列函数
                    函数名称     函数作用
                    class_addIvar     为类添加实例变量
                    class_addProperty     为类添加属性
                    class_addMethod     为类添加方法
                    class_addProtocol     为类遵循协议
                    class_replaceMethod     替换类某方法的实现
                    class_getName     获取类名
                    class_isMetaClass     判断是否为元类
                    objc_getProtocol     获取某个协议
                    objc_copyProtocolList     拷贝在运行时中注册过的协议列表
                    class_getSuperclass     获取某类的父类
                    class_setSuperclass     设置某类的父类
                    class_getProperty     获取某类的属性
                    class_getInstanceVariable     获取实例变量
                    class_getClassVariable     获取类变量
                    class_getInstanceMethod     获取实例方法
                    class_getClassMethod     获取类方法
                    class_getMethodImplementation     获取方法的实现
                    class_getInstanceSize     获取类的实例的大小
                    class_respondsToSelector     判断类是否实现某方法
                    class_conformsToProtocol     判断类是否遵循某协议
                    class_createInstance     创建类的实例
                    class_copyIvarList     拷贝类的实例变量列表
                    class_copyMethodList     拷贝类的方法列表
                    class_copyProtocolList     拷贝类遵循的协议列表
                    class_copyPropertyList     拷贝类的属性列表

                    objcet_*

                    objcet_系列函数关注于对象的角度,如实例变量

                    // 3.object_xxx 系列函数
                    函数名称     函数作用
                    object_copy     对象copy(ARC无效)
                    object_dispose     对象释放(ARC无效)
                    object_getClassName     获取对象的类名
                    object_getClass     获取对象的Class
                    object_setClass     设置对象的Class
                    object_getIvar     获取对象中实例变量的值
                    object_setIvar     设置对象中实例变量的值
                    object_getInstanceVariable     获取对象中实例变量的值 (ARC中无效,使用object_getIvar)
                    object_setInstanceVariable     设置对象中实例变量的值 (ARC中无效,使用object_setIvar)

                    method_*

                    method_系列函数关注于方法内部,如果方法的参数及返回值类型和方法的实现

                    // 4.method_xxx 系列函数
                    函数名称     函数作用
                    method_getName     获取方法名
                    method_getImplementation     获取方法的实现
                    method_getTypeEncoding     获取方法的类型编码
                    method_getNumberOfArguments     获取方法的参数个数
                    method_copyReturnType     拷贝方法的返回类型
                    method_getReturnType     获取方法的返回类型
                    method_copyArgumentType     拷贝方法的参数类型
                    method_getArgumentType     获取方法的参数类型
                    method_getDescription     获取方法的描述
                    method_setImplementation     设置方法的实现
                    method_exchangeImplementations     替换方法的实现

                    property_*

                    property_系类函数关注与属性*内部,如属性的特性等

                    // 5.property_xxx 系列函数
                    函数名称     函数作用
                    property_getName     获取属性名
                    property_getAttributes     获取属性的特性列表
                    property_copyAttributeList     拷贝属性的特性列表
                    property_copyAttributeValue     拷贝属性中某特性的值

                    protocol_*

                    // 6.protocol_xxx 系列函数
                    函数名称     函数作用
                    protocol_conformsToProtocol     判断一个协议是否遵循另一个协议
                    protocol_isEqual     判断两个协议是否一致
                    protocol_getName     获取协议名称
                    protocol_copyPropertyList     拷贝协议的属性列表
                    protocol_copyProtocolList     拷贝某协议所遵循的协议列表
                    protocol_copyMethodDescriptionList     拷贝协议的方法列表
                    protocol_addProtocol     为一个协议遵循另一协议
                    protocol_addProperty     为协议添加属性
                    protocol_getProperty     获取协议中的某个属性
                    protocol_addMethodDescription     为协议添加方法描述
                    protocol_getMethodDescription     获取协议中某方法的描述

                    ivar_*

                    // 7.ivar_xxx 系列函数
                    函数名称     函数作用
                    ivar_getName     获取Ivar名称
                    ivar_getTypeEncoding     获取类型编码
                    ivar_getOffset     获取偏移量

                    sel_*

                    // 8.sel_xxx 系列函数
                    函数名称     函数作用
                    sel_getName     获取名称
                    sel_getUid     注册方法
                    sel_registerName     注册方法
                    sel_isEqual     判断方法是否相等

                    imp_*

                    // 9.imp_xxx 系列函数
                    函数名称     函数作用
                    imp_implementationWithBlock     通过代码块创建IMP
                    imp_getBlock     获取函数指针中的代码块
                    imp_removeBlock     移除IMP中的代码块

                    到此这篇关于iOS开发之Objective-c的Runtime理解指南的文章就介绍到这了,更多相关Objective-c的Runtime理解指南内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

                    您可能感兴趣的文章:
                    • 总结iOS中runtime的使用
                    • iOS runtime动态添加方法示例详解
                    • iOS Runtime详解(新手也看得懂)
                    • iOS runtime forwardInvocation详解及整理
                    • IOS Object-C 中Runtime详解及实例代码

                    用户评论