iOS主要知识点梳理回顾-4-运行时类和实例的操作
类和实例的操作
iOS 运行时(Objective-C Runtime)提供了丰富的 API 来对类进行动态操作,包括创建类、修改类的结构、添加方法、替换方法等。这对于实现动态特性、AOP(面向切面编程)、方法拦截等功能非常重要。以下举例
- 创建并注册类(objc_allocateClassPair、
objc_registerClassPair) - 关联对象(objc_setAssociatedObject、objc_getAssociatedObject)
- 添加、替换方法(
class_addMethod、class_replaceMethod) - 获取类的信息(class_copyPropertyList、class_copyMethodList)
1. 创建类和元类
API:
-
objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)创建一个新的类,并指定其父类及额外的内存空间。 -
objc_registerClassPair(Class cls)注册类以使其能够使用。
#import <objc/runtime.h>void dynamicMethodIMP(id self, SEL _cmd) {NSLog(@"Dynamic method invoked!");
}- (void)createDynamicClass {// 创建一个新类,继承自NSObjectClass newClass = objc_allocateClassPair([NSObject class], "DynamicClass", 0);// 为类添加一个方法class_addMethod(newClass, @selector(dynamicMethod), (IMP)dynamicMethodIMP, "v@:");// 注册类objc_registerClassPair(newClass);// 创建实例并调用动态方法id instance = [[newClass alloc] init];[instance performSelector:@selector(dynamicMethod)];
}
动态创建类和元类在实际业务中的应用场景主要集中在以下方面:
- 框架封装与底层实现:如 KVO、AOP、热修复。
- 插件化与组件化:按需加载模块,提升扩展性。
- 跨平台 UI 框架支持:动态生成控件映射类。
2. 添加属性或者关联对象
通过class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount) 添加属性。
- (void)addDynamicProperty {objc_property_attribute_t type = { "T", "@\"NSString\"" }; // 属性类型objc_property_attribute_t ownership = { "C", "" }; // C代表copyobjc_property_attribute_t backingivar = { "V", "_dynamicProperty" }; // 关联ivarobjc_property_attribute_t attrs[] = { type, ownership, backingivar };class_addProperty([self class], "dynamicProperty", attrs, 3);
}
需要注意的是,这样添加完成之后,并不能访问属性,因为它不会自动生成访问方法(getter、setter),如果要用,还需要通过前面的添加方法来配置getter、setter。真想不通,这玩意有啥用,反正我没用过。
倒不如咱们经常用的借助类别+属性关联来的直接,不过这不是动态特性了。
/// .h文件
@interface UIImage (Help)/// name
@property (nonatomic, copy) NSString *imageName;@end/// .m文件
@implementation UIViewController(Help)- (NSString *)imageName {return objc_getAssociatedObject(self, @selector(imageName));
}- (void)setImageName:(NSString *)imageName {objc_setAssociatedObject(self, @selector(imageName), imageName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}@end
3. 添加、替换方法
API:
-
class_addMethod(Class cls, SEL name, IMP imp, const char *types),添加方法。 -
class_replaceMethod(Class cls, SEL name, IMP imp, const char *types),替换方法,如果方法不存在则添加。 -
method_setImplementation(Method m, IMP imp),修改方法实现。
void newMethodIMP(id self, SEL _cmd) {NSLog(@"New method implementation called!");
}- (void)addOrReplaceMethod {Class cls = [TestClass class];SEL originalSelector = @selector(oldMethod);SEL newSelector = @selector(newMethod);// 替换方法Method originalMethod = class_getInstanceMethod(cls, originalSelector);class_replaceMethod(cls, originalSelector, (IMP)newMethodIMP, method_getTypeEncoding(originalMethod));
}
以上,替换后,我们再执行TestClass的oldMethod就会打印"New method implementation called!"
4. 获取类和方法信息
API:
class_getName(Class cls)获取类名class_getSuperclass(Class cls)获取父类class_getInstanceMethod(Class cls, SEL name)获取实例方法class_getClassMethod(Class cls, SEL name)获取类方法class_copyMethodList(Class cls, unsigned int *outCount)获取方法列表
- (void)listMethodsOfClass:(Class)cls {unsigned int methodCount = 0;Method *methodList = class_copyMethodList(cls, &methodCount);for (unsigned int i = 0; i < methodCount; i++) {SEL methodName = method_getName(methodList[i]);NSLog(@"Method: %@", NSStringFromSelector(methodName));}free(methodList);
}
以上,自己实操,看看效果更好一些
相关文章:
iOS主要知识点梳理回顾-4-运行时类和实例的操作
类和实例的操作 iOS 运行时(Objective-C Runtime)提供了丰富的 API 来对类进行动态操作,包括创建类、修改类的结构、添加方法、替换方法等。这对于实现动态特性、AOP(面向切面编程)、方法拦截等功能非常重要。以下举例…...
vue2和vue3生命周期的区别通俗易懂
用最直白的对比帮你理解 Vue2 和 Vue3 生命周期的区别,就像对比手机系统的升级: 一、生命周期阶段对比表(老手机 vs 新手机) 阶段Vue2(老系统)Vue3(新系统)变化说明初始化beforeCre…...
使用 meshgrid函数绘制网格点坐标的原理与代码实现
使用 meshgrid 绘制网格点坐标的原理与代码实现 在 MATLAB 中,meshgrid 是一个常用函数,用于生成二维平面网格点的坐标矩阵。本文将详细介绍如何利用 meshgrid 函数生成的矩阵绘制网格点的坐标,并给出具体的代码实现和原理解析。 实现思路 …...
postgresql源码学习(59)—— 磁盘管理器 SMGR
一、 定义及作用 PostgreSQL 的磁盘管理器(Storage Manager,简称 SMGR)是数据库系统中负责管理底层存储的核心模块。磁盘管理器并非直接操作磁盘上的文件,而是通过VFD(虚拟文件描述符,将在后续学习…...
Spring Boot(8)深入理解 @Autowired 注解:使用场景与实战示例
搞个引言 在 Spring 框架的开发中,依赖注入(Dependency Injection,简称 DI)是它的一个核心特性,它能够让代码更加模块化、可测试,并且易于维护。而 Autowired 注解作为 Spring 实现依赖注入的关键工具&…...
UE_C++ —— Structs
目录 一,实现一个UStruct 二,Struct Specifiers 三,最佳做法与技巧 结构体(Struct)是一种帮助组织和操作相关属性的数据结构;在引擎中,结构体会被引擎反射系统识别为 UStruct,但不…...
ArcGISPro 新建shp+数据结构
import arcpy# 设置工作空间和 Shapefile 存放路径 shp_path r"C:\path\to\your\folder\PolygonZY.shp" # Shapefile 存放路径 fields [("CHBH", "TEXT", 20),("ZCMC", "TEXT", 100),("ZCLX", "TEXT"…...
DeepSeek教unity------MessagePack-06
无类型 Typeless 无类型的 API 类似于 BinaryFormatter,因为它会将类型信息嵌入到数据块中,所以在调用 API 时不需要显式指定类型。 MessagePackSerializer.Typeless 是 Serialize/Deserialize<object>(TypelessContractlessStandardResolver.In…...
2.【BUUCTF】bestphp‘s revenge
进入题目页面如下 进行代码审计 <?php // 1. 高亮显示当前PHP文件的源代码,方便开发者查看代码内容,在生产环境中不应使用此函数,可能会导致代码泄露。 highlight_file(__FILE__);// 2. 定义变量 $b ,其值为字符串 implode &…...
《刚刚问世》系列初窥篇-Java+Playwright自动化测试-23- 操作鼠标拖拽 - 番外篇(详细教程)
拉票 亲爱的小伙伴们或者童鞋们,喜欢宏哥文章的,请动动你们发财小手,给我投投票票 。 祝2025小伙伴们工作顺利,家庭和睦,心想事成,财源滚滚! 我的票还有7票,互票的朋友私信给我。 投…...
Netty源码解析之异步处理(二):盛赞Promise中的集合设计
前言 在阅读Netty源码的过程中,我越来越相信一句话:“Netty的源码非常好,质量极高,是Java中质量最高的开源项目之一”。如果认真研究,会有一种遍地黄金的感觉。 本篇文件我将记录一下鄙人在Promise的实现类DefaultPr…...
NetworkX布局算法:nx.spring_layout
诸神缄默不语-个人CSDN博文目录 官方文档:https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.spring_layout.html 和nx.fruchterman_reingold_layout()等价。 这个函数主要是为了在可视化NetworkX图时设置节点分布布局的&…...
Navicat导入海量Excel数据到数据库(简易介绍)
目录 前言正文 前言 此处主要作为科普帖进行记录 原先Java处理海量数据的导入时,由于接口超时,数据处理不过来,后续转为Navicat Navicat 是一款功能强大的数据库管理工具,支持多种数据库系统(如 MySQL、PostgreSQL、…...
LeetCodehot100 力扣热题100 二叉树展开为链表
代码思路 目标: 将二叉树展平(flatten)为一个单链表。展平后的链表应该按照前序遍历的顺序排列节点,即: • 节点的左子树指针设置为 nullptr。 • 节点的右子树指针指向下一个节点。 代码注释及思路 class Solution…...
2.14学习总结
#include <stdio.h> #include <stdlib.h> #include <math.h>#define MAX_N 32767// 二分查找最接近目标值的元素 int binarySearch(int* arr, int left, int right, int target) {while (left < right) {int mid left (right - left) / 2;if (arr[mid] …...
在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程
既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…...
zola + github page,用 workflows 部署
之前的Zola都是本地build之后,再push到github上,这种方式很明显的弊端就是只能在本地编辑,而不能通过github编辑,再pull到本地,缺乏了灵活性。因此将zola用workflows来部署。 repo地址:https://github.com/…...
【科技革命】颠覆性力量与社会伦理的再平衡
目录 2025年科技革命:颠覆性力量与社会伦理的再平衡目录技术突破全景图认知智能的范式转移量子霸权实现路径生物编程技术革命能源结构重构工程 产业生态链重构医疗健康新范式教育系统智能进化金融基础设施变革制造范式革命 科技伦理与文明演进 2025年科技革命&#…...
UIView 与 CALayer 的联系和区别
今天说一下UIView 与 CALayer 一、UIView 和 CALayer 的关系 在 iOS 开发中,UIView 是用户界面的基础,它负责处理用户交互和绘制内容,而 CALayer 是 UIView 内部用于显示内容的核心图层(Layer)。每个 UIView 内部都有…...
Jenkins 新建配置 Freestyle project 任务 六
Jenkins 新建配置 Freestyle project 任务 六 一、新建任务 在 Jenkins 界面 点击 New Item 点击 Apply 点击 Save 回到任务主界面 二、General 点击左侧 Configure Description:任务描述 勾选 Discard old builds Discard old builds:控制何时…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
