iOS的Runtime知识点繁杂难啃,真的理解它的思想,你就豁然开朗了
一、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机制:先查询本类是否又该方法的实现--->如果没有逐级找父类,还有一个快速映射表(提高性能)---> 匹配方法 ---> 设置一个执行者---> 消息转发 ---> 没有实现方法
re solveInstanceMethod 决策实力,动态方法解析
forwardingTargetForSelector 转寄Target ,设置一个执行者 备用接收者
MethodSignatureForSelector 方法签名,
forwardInvocation 转寄求助,消息重定向
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的Runtime知识点繁杂难啃,真的理解它的思想,你就豁然开朗了的更多相关文章
- 关于iOS的runtime
runtime是一个很有意思的东西,如果你学iOS开发很经常就会用到或被问到runtime.那么runtime是什么呢,如何去了解它. runtime:中文名 运行时,系统在编译时留下的一些 类型,操 ...
- ios之runtime学习
今天学习了一下ios的runtime,看了其他博主的博客写的很不错,自己就不班门弄斧了,仅在此转载: 1.关于oc中类和元类:http://husbandman.diandian.com/post/2 ...
- IOS 中runtime 不可变数组__NSArray0 和__NSArrayI
IOS 中runtime 不可变数组__NSArray0 和__NSArrayI 大家可能都遇到过项目中不可变数组避免数组越界的处理:runtime,然而有时候并不能解决所有的问题,因为类簇不一样 # ...
- ios的一些知识点
ios的一些知识点 一 非ARC的内存管理情况 1-autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段落,开 ...
- (转载)ios的一些知识点
ios的一些知识点 一 非ARC的内存管理情况 1-autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一 段落 ...
- iOS运用runtime全局修改UILabel的默认字体
iOS运用runtime全局修改UILabel的默认字体 一.需求背景介绍 在项目比较成熟的基础上,遇到了这样一个需求,应用中需要引入新的字体,需要更换所有Label的默认字体,但是同时,对于一些特殊 ...
- iOS开发-Runtime详解
iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...
- 【转】你真的理解Python中MRO算法吗?
你真的理解Python中MRO算法吗? MRO(Method Resolution Order):方法解析顺序. Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多 ...
- 我想这次我真的理解了 JavaScript 的单线程机制
今天面试的时候被问到一个问题,是关于 JS 异步的.当时我脑海中闪过了一个单线程的概念,但却没有把真正的原理阐述清楚.所以回来特意重新回顾了前面单线程和异步相关的一些知识点. 虽然之前学习的时候也接触 ...
- 你真的理解Java 注解吗?
你真的理解Java 注解吗? 1.什么是注解? 官方解释: Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.Java ...
随机推荐
- CoreMark简单学习
CoreMark简单学习 下载 https://github.com/eembc/coremark-pro 需要注意, 其实coremark是有两组. 一组是coremark 一组是 coremark ...
- ActiveReports报表行号
=RunningValue(Fields!字段名称.Value, CountDistinct, "矩表分组名称") RunningValue(Fields!区域.Value, Co ...
- SqlSugar多库/多租户
1. 多库和多租户 如果是接口ISugarClient先看一下标题6,看完在看这儿 1.1 固定多数据库模式 数据库数量是固定的一般在声明的全部加上 //通过ConfigId进行数据库区分 var d ...
- 【7】vscode不同的窗口样式和颜色插件peacock、设置打开多个窗口、md文件打开方式和预览以及插入目录
相关文章: [1]VScode中文界面方法-------超简单教程 [2]VScode搭建python和tensorflow环境 [3]VSCode 主题设置推荐,自定义配色方案,修改注释高亮颜色 [ ...
- Win32汇编:算数运算指令总结
整理复习汇编语言的知识点,以前在学习<Intel汇编语言程序设计 - 第五版>时没有很认真的整理笔记,主要因为当时是以学习理解为目的没有整理的很详细,这次是我第三次阅读此书,每一次阅读都会 ...
- C# 笔记之基本语法
C#是一种现代的.通用的编程语言,由微软公司开发和推广.它于2000年发布,是一种结构化.面向对象和组件化的语言,旨在为Windows操作系统和Microsoft .NET框架提供强大的支持.可用于开 ...
- 记一次在服务器上运行node.js程序时无法通过nohup xxx & 方式挂起的问题
由于业务需求 每天要在服务器上整理一组数据,为了方便就用node.js来写了.但是运行的时候发现了一个问题 明明使用了nohup main.js &的方式后台运行了程序 但是一旦我关闭了she ...
- Tauri VS. Electron - 真实项目的比较
文章翻译自:Tauri VS. Electron - Real world application 以下是正文: 在这篇文章中我将会用真实的项目来比较 Electron 和 Tauri: Authme ...
- C++小项目|2022期末大作业
前言 那么这里博主先安利一下一些干货满满的专栏啦! 手撕数据结构https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014. ...
- ASP.NET Core 6.0+Vue.js 3 实战开发(视频)
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章或视频能成为你成长路上的垫脚石. 录制视频的体验 这是一个收费的视频,很抱歉,让您失望了. 我尝试做点收费的视频,不是因为我不 ...