当前位置: 首页 > news >正文

iOS runtime理解和应用场景

一、runtime的动态性

OC的运行时系统(Runtime System)提供了丰富的动态特性,包括类与对象的创建、消息发送与转发、方法的动态添加与替换、属性的动态合成等。通过使用运行时库提供的API,可以在运行时获取和操作类与对象的信息,实现各种动态性的功能。

 我对 Runtime 的理解是,它是 Objective-C 语言的核心之一,为我们提供了一种在程序运行时动态操作类和对象的能力。通过 Runtime,我们可以在不修改源代码的情况下,实现诸如动态创建类、添加成员变量、调用方法、交换方法实现等功能,从而实现更灵活、更动态的编程方式。

二、应用场景

1、实现Runtime在分类创建属性(添加关联对象)

当使用 Objective-C 的分类来添加属性时,通常情况下是无法直接在分类中声明实例变量的,因为分类不允许添加实例变量。但是,我们可以利用 Runtime 来实现在分类中添加属性的功能,具体步骤如下:

  1. 定义关联的键值:为了关联属性和其对应的存取方法,需要定义一个全局唯一的键值。

  2. 实现属性的 getter 和 setter 方法:在分类中实现属性的 getter 和 setter 方法,这些方法将通过 Runtime 添加到分类中。

  3. 使用 Runtime 添加属性:在分类的实现文件中,通过 Runtime 的函数来动态地为类添加属性。

下面是一个示例代码,演示了如何使用 Runtime 在分类中添加属性:

#import <objc/runtime.h>// 定义关联的键值
static char kAssociatedObjectKey;@interface NSObject (MyCategory)// 声明属性
@property (nonatomic, strong) NSString *myProperty;@end@implementation NSObject (MyCategory)// 实现属性的 getter 方法
- (NSString *)myProperty {// 使用关联对象获取属性值return objc_getAssociatedObject(self, &kAssociatedObjectKey);
}// 实现属性的 setter 方法
- (void)setMyProperty:(NSString *)myProperty {// 使用关联对象设置属性值objc_setAssociatedObject(self, &kAssociatedObjectKey, myProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}@end

2--黑魔法:交换方法用于统一处理某个方法

管理类方法.h

#import <Foundation/Foundation.h>@interface AARunTimeUtility : NSObject
/**交换实例方法@param cls 当前class@param originalSelector originalSelector description@param swizzledSelector swizzledSelector description@return 返回*/
+ (BOOL)swizzlingInstanceMethodInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;/**交换类方法@param cls 当前class@param originalSelector originalSelector description@param swizzledSelector swizzledSelector description@return 成*/
+ (BOOL)swizzlingClassMethodInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;@end

.m文件

#import "AARunTimeUtility.h"
#import <objc/runtime.h>@implementation AARunTimeUtility+ (BOOL)swizzlingInstanceMethodInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector
{Class class = cls;Method originalMethod = class_getInstanceMethod(class, originalSelector);Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));if (didAddMethod){class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));}else{method_exchangeImplementations(originalMethod, swizzledMethod);}return didAddMethod;
}+ (BOOL)swizzlingClassMethodInClass:(Class)cls originalSelector:(SEL)origi

相关文章:

  • 前端性能基础测试研究
  • Java面试题:工厂模式与内存泄漏防范?线程安全与volatile关键字的适用性?并发集合与线程池管理问题
  • CUDA下载安装与配置
  • 简单了解TCP/IP四层模型
  • 基于PHP的数字化档案管理系统
  • 接口隔离原则的实现方法及具体应用
  • VScode(Python)使用ssh远程开发(Linux系统树莓派)时,配置falke8和yapf总结避坑!最详细,一步到位!
  • Spring中的注释
  • matplotlib-散点图
  • 2023年第三届中国高校大数据挑战赛第二场赛题C:用户对博物馆评论的情感分析(附上代码与详细视频讲解)
  • SplitFunctions (BOLT) - 优化阅读笔记
  • 实践致知第9享:Word中标题编号无法正常编辑
  • Go微服务实战——服务的配置获取(nacos做配置中心)
  • InnoDB对MVCC的实现
  • 2024年测量技术与传感仪器国际学术会议(ICMTSI 2024)
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • 345-反转字符串中的元音字母
  • es的写入过程
  • IndexedDB
  • jdbc就是这么简单
  • LeetCode算法系列_0891_子序列宽度之和
  • SSH 免密登录
  • 阿里云应用高可用服务公测发布
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 聊一聊前端的监控
  • 前端技术周刊 2019-02-11 Serverless
  • 思考 CSS 架构
  • 跳前端坑前,先看看这个!!
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • (3)选择元素——(17)练习(Exercises)
  • (C#)一个最简单的链表类
  • (分布式缓存)Redis哨兵
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (转) 深度模型优化性能 调参
  • .axf 转化 .bin文件 的方法
  • .Net Core和.Net Standard直观理解
  • .Net Remoting常用部署结构
  • .net6使用Sejil可视化日志
  • .Net6使用WebSocket与前端进行通信
  • .NET的数据绑定
  • //解决validator验证插件多个name相同只验证第一的问题
  • /proc/stat文件详解(翻译)
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @RequestMapping-占位符映射
  • @SentinelResource详解
  • [C++]打开新世界的大门之C++入门
  • [EFI]Dell Inspiron 15 5567 电脑 Hackintosh 黑苹果efi引导文件
  • [Electron]ipcMain.on和ipcMain.handle的区别
  • [IE编程] 打开/关闭IE8的光标浏览模式(Caret Browsing)
  • [js] 正则表达式
  • [Leetcode] 寻找数组的中心索引