[TOC]
本篇英文名叫 OC Runtime In Action:CEO Cook Actually Used In Cooking
,翻译过来的意思是开发人员实际开发的时候使用的 runtime 操作。进行积累整理。
隶属于我的第二个大系列 CWC
:Cooking With Cook
,翻译过来的中文意思就是 作为一个长期热爱苹果的苹果开发者,陪着水果公司一起积累和成长。
首先简单罗列一下大部分的 runtime 的 API 方法
#0. runtime方法概要
NSObject部分:
1 | // 根据 instance 对象或者类名获得一个 class 对象 |
Class 部分:
1 | // 动态创建一对类和元类(参数:父类,类名,额外的内存空间) |
Property iVar 相关:
1 | // 获取一个实例变量信息 |
属性相关:
1 | // 获取一个属性 |
Method 相关:
1 | // 获得一个实例方法、类方法 |
关联对象相关:
1 | // 添加关联对象 |
1. 接触 Runtime 的方式
正常开发的时候,我们通过三个渠道来接触到runtime
- OC 层面, eg:
@selector
- Runtime API, eg:
objc-getclass()
这些方法,msgSend()
,setassosiciatedObject()
等 - NSObject 相关的 API, eg:
2. 在lldb中打印 objc_class
isa 的指向类
这点虽然不是调用runtime,但是涉及到了isa指针的相关知识。
直接通过位运算与上掩码来取类指针
这里与操作后面的值就是 ISAMASK,根据操作平台不同。
3. 通过 @encode 打印所有的type encodings
这个还是有用的,因为其实 method_t 里面满共就三四个值,一个name,一个imp实现指针,一个就是方法的 TypeEncodings
1 |
|
1 | 2020-11-01 15:21:03.434385+0800 001-类的属性与变量[34325:1798027] char --> c |
4. 打印所有的类的属性
1 |
|
#5. 查找 方法
不像上一点那么通用,需要手动查是否包含该方法
1 |
|
6. print all properties
1 | //- (void)printClassAllProperties:(Class)cls { |
另外这里有一个另外的函数,读取property 的 attribute,property_getAttributes(property)
打印出来会比如这种:T@"NSString",C,N,V_name
T:Type
C:copy
N:nonatomic
V:variable
7. 假装的本地 struct 逻辑结构
研究 bucket 的时候用到的。
因为除非是源码环境,否则业务环境工程我们拿不到源码的结构体,所以怎么办,只能自己写,假装我们有,在业务环境把源码环境骗过来:
1 | typedef uint32_t mask_t; // x86_64 & arm64 asm are less efficient with 16-bits |
8. instrumentObjcMessageSends
iOS, this works only on Simulator.
calling:
(void)instrumentObjcMessageSends(YES);
When I need to start logging all messages and then:
(void)instrumentObjcMessageSends(NO);
Don’t forget to add #import <objc/runtime.h>.
When I don’t need it anymore. The annoying thing is that the log is created under /tmp/msgSends-
and this means that you have to open the terminal and use tail to see it in a readable way.
What is printed is something like this:
1 | - CustomTableViewController UIViewController _parentModalViewController |
这个方法的源码如下:
1 | void instrumentObjcMessageSends(BOOL flag) |
9. 一些常见API的区别
iOS中内省的几个方法?
isMemberOfClass //对象是否是某个类型的对象
isKindOfClass //对象是否是某个类型或某个类型子类的对象
isSubclassOfClass //某个类对象是否是另一个类型的子类
isAncestorOfObject //某个类对象是否是另一个类型的父类
respondsToSelector //是否能响应某个方法
conformsToProtocol //是否遵循某个协议
10. 打印类和子类 + 打印所有方法
1 |
|
参考链接:
Apple objc4 源码
Apple OC Runtime Document
GUNStep
- Post link: http://yangzai360.top/2020/11/10/CWC02_OCRuntimeInAction_CookActuallyUsedInCooking/
- Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.