4

runtime的实际应用

 3 years ago
source link: https://www.jianshu.com/p/9f578423d2b3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

runtime的实际应用

2019.05.13 15:00:07字数 733阅读 75
1、使用关联对象动态给分类添加属性

使用关联对象,可以为类添加Category中的属性,我们可以为现有类添加一些实用的方法和属性。

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
id objc_getAssociatedObject(id object, const void *key);
void objc_removeAssociatedObjects(id object);
2、hook方法,替换系统方法,拦截方法等
  • 当我们发现系统方法的原生实现无法满足我们的某些需求时,我们就可以替换掉系统方法的原生实现,为其添加一些我们的定制化需求。比如:
    1.防止崩溃(hook forwardInvocation转发给safeProxy对象处理);
    2.防止按钮点击过快(为uicontrol分类添加属性acceptEventInterval、canPerformEvent,并hook (sendAction:to:forEvent:));
    3.从全局上为导航栏添加返回按钮;
    4.刷新tableView、collectionView时,自动判断是否显示暂无数据提示图等。
  • 我们使用别人的三方库,库里有些方法无法满足我们的需求或者有bug,我们也最好使用黑魔法来处理,而不是直接去该三方库的源码,因为你改了源码后一旦更新了三方库,问题就又出来了。
3、字典模型转换

MJExtension是一个字典模型转换工具,是通过runtime实现的,主要步骤如下:
1)首先使用runtime中的class_copyPropertyList方法,获取类的所有属性,
2)然后遍历每个成员,首先使用property_getName获取属性名,然后使用property_getAttributes获取objc_property_attribute_t,为一个字符串的结果,里面包含属性名称、属性编码类型、原子类型/非原子类型等。

/* 成员变量:
     * class_copyIvarList(__unsafe_unretained Class cls, unsigned int *outCount)
     * 方法:
     * class_copyMethodList(__unsafe_unretained Class cls, unsigned int *outCount)
     * 属性:
     * class_copyPropertyList(__unsafe_unretained Class cls, unsigned int *outCount)
     * 协议:
     * class_copyProtocolList(__unsafe_unretained Class cls, unsigned int *outCount)
     */
4、对象自动归档解档

Ivar *ivars = class_copyIvarList([Person class], &count);

5、获取所有的私有属性和方法

Ivar *ivars= class_copyIvarList([UIPageControl class], &count);
Method *memberFuncs = class_copyMethodList([UIPageControl class], &count);

6、消息转发,崩溃拦截

unrecognized selector类型的crash在app众多的crash类型中占着比较大的成分,通常是因为一个对象调用了一个不属于它方法的方法导致的。
我们知道,在一个函数找不到时,runtime提供了三种方式去补救:
1、调用resolveInstanceMethod给个机会让类添加这个实现这个函数
2、调用forwardingTargetForSelector让别的对象去执行这个函数
3、调用forwardInvocation(函数执行器)灵活的将目标函数以其他形式执行。
所以我们可以在这三个方法中添加实现,来响应这个方法,避免崩溃。

7、实现协议转发,进行AB测试

通过runtime的消息转发机制,方法调用,转移到不同的对象中,实现AB方法,避免AB方案代码柔和到同一文件中,通过if和else判断实现。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK