iOS - Runtime-API

news2024/11/17 5:39:14

文章目录

  • iOS - Runtime-API
    • 1. Runtime应用
      • 1.1 字典转模型
      • 1.2 替换方法实现
      • 1.3 利用关联对象给分类添加属性
      • 1.4 利用消息转发机制,解决方法找不到的异常问题
    • 2. Runtime-API
      • 2.1 Runtime API01 – 类
        • 2.1.1 动态创建一个类(参数:父类,类名,额外的内存空间)
          • 2.2.1.1 示例
        • 2.2.1 注册一个类(要在类注册之前添加成员变量)
          • 2.2.2.1 示例
        • 2.2.3 销毁一个类
        • 2.2.4 获取isa指向的Class
        • 2.2.5 设置isa指向的Class
          • 2.2.5.1 示例
          • 2.2.5.2 调试信息
        • 2.2.6 判断一个OC对象是否为Class
          • 2.2.6.1 示例
        • 2.2.7 判断一个Class是否为元类
          • 2.2.7.1 示例
        • 2.2.8 获取父类
      • 2.2 Runtime API02 – 成员变量
        • 2.2.1 获取一个实例变量信息
        • 2.2.2 拷贝实例变量列表(最后需要调用free释放)
        • 2.2.3 设置和获取成员变量的值
        • 2.2.4 动态添加成员变量(已经注册的类是不能动态添加成员变量的)
        • 2.2.5 获取成员变量的相关信息
      • 2.3 Runtime API03 – 属性
        • 2.3.1 获取一个属性
        • 2.3.2 拷贝属性列表(最后需要调用free释放)
        • 2.3.3 动态添加属性
        • 2.3.4 动态替换属性
        • 2.3.5 获取属性的一些信息
      • 2.4 Runtime API04 – 方法
        • 2.4.1 获得一个实例方法、类方法
        • 2.4.2 方法实现相关操作
        • 2.4.3 拷贝方法列表(最后需要调用free释放)
        • 2.4.4 动态添加方法
        • 2.4.5 动态替换方法
        • 2.4.6 获取方法的相关信息(带有copy的需要调用free去释放)
    • 3. 示例
      • 3.1 示例1
      • 3.2 示例2
      • 3.3 示例3

iOS - Runtime-API

1. Runtime应用

开发过程中经常会用到Runtime,比如:

1.1 字典转模型

  • 利用Runtime遍历所有的属性或者成员变量
  • 利用KVC设值

1.2 替换方法实现

  • class_replaceMethod
  • method_exchangeImplementations

1.3 利用关联对象给分类添加属性

1.4 利用消息转发机制,解决方法找不到的异常问题

2. Runtime-API

2.1 Runtime API01 – 类

2.1.1 动态创建一个类(参数:父类,类名,额外的内存空间)
  • Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
2.2.1.1 示例
// 动态创建一个类
Class newClass = objc_allocateClassPair([NSObject class], "ZSXDog", 0);
id dog = [[newClass alloc] init];
NSLog(@"");

执行结果:

2.2.1 注册一个类(要在类注册之前添加成员变量)
  • void objc_registerClassPair(Class cls)
2.2.2.1 示例
// 注册类
objc_registerClassPair(newClass);
2.2.3 销毁一个类
  • void objc_disposeClassPair(Class cls)
2.2.4 获取isa指向的Class
  • Class object_getClass(id obj)
2.2.5 设置isa指向的Class
  • Class object_setClass(id obj, Class cls)
2.2.5.1 示例
ZSXPerson *person = [[ZSXPerson alloc] init];
[person run];
    
// 设置isa指向的Class
object_setClass(person, [ZSXCat class]);
[person run];

执行结果:

2.2.5.2 调试信息


2.2.6 判断一个OC对象是否为Class
  • BOOL object_isClass(id obj)
2.2.6.1 示例
ZSXPerson *person = [[ZSXPerson alloc] init];
NSLog(@"%d %d %d", object_isClass(person), object_isClass([ZSXPerson class]), object_isClass(object_getClass([ZSXPerson class])));

执行结果:

2.2.7 判断一个Class是否为元类
  • BOOL class_isMetaClass(Class cls)
2.2.7.1 示例
NSLog(@"%d %d", class_isMetaClass([ZSXPerson class]), class_isMetaClass(object_getClass([ZSXPerson class])));

执行结果:

2.2.8 获取父类
  • Class class_getSuperclass(Class cls)

2.2 Runtime API02 – 成员变量

2.2.1 获取一个实例变量信息
  • Ivar class_getInstanceVariable(Class cls, const char *name)
2.2.2 拷贝实例变量列表(最后需要调用free释放)
  • Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
2.2.3 设置和获取成员变量的值
  • void object_setIvar(id obj, Ivar ivar, id value)
  • id object_getIvar(id obj, Ivar ivar)
2.2.4 动态添加成员变量(已经注册的类是不能动态添加成员变量的)
  • BOOL class_addIvar(Class cls, const char * name, size_t size, uint8_t alignment, const char * types)
2.2.5 获取成员变量的相关信息
  • const char *ivar_getName(Ivar v)
  • const char *ivar_getTypeEncoding(Ivar v)

2.3 Runtime API03 – 属性

2.3.1 获取一个属性
  • objc_property_t class_getProperty(Class cls, const char *name)
2.3.2 拷贝属性列表(最后需要调用free释放)
  • objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
2.3.3 动态添加属性

BOOL class_addProperty(Class cls, const char *name, const objc_property_attribute_t *attributes,
unsigned int attributeCount)

2.3.4 动态替换属性
  • void class_replaceProperty(Class cls, const char *name, const objc_property_attribute_t *attributes,
    unsigned int attributeCount)
2.3.5 获取属性的一些信息
  • const char *property_getName(objc_property_t property)
  • const char *property_getAttributes(objc_property_t property)

2.4 Runtime API04 – 方法

2.4.1 获得一个实例方法、类方法
  • Method class_getInstanceMethod(Class cls, SEL name)
  • Method class_getClassMethod(Class cls, SEL name)
2.4.2 方法实现相关操作
  • IMP class_getMethodImplementation(Class cls, SEL name)
  • IMP method_setImplementation(Method m, IMP imp)
  • void method_exchangeImplementations(Method m1, Method m2)
2.4.3 拷贝方法列表(最后需要调用free释放)
  • Method *class_copyMethodList(Class cls, unsigned int *outCount)
2.4.4 动态添加方法
  • BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
2.4.5 动态替换方法
  • IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
2.4.6 获取方法的相关信息(带有copy的需要调用free去释放)
  • SEL method_getName(Method m)
  • IMP method_getImplementation(Method m)
  • const char *method_getTypeEncoding(Method m)
  • unsigned int method_getNumberOfArguments(Method m)
  • char *method_copyReturnType(Method m)
  • char *method_copyArgumentType(Method m, unsigned int index)

3. 示例

3.1 示例1

// 动态创建一个类
Class newClass = objc_allocateClassPair([NSObject class], "ZSXDog", 0);
// 添加成员变量
class_addIvar(newClass, "_age", 4, 1, @encode(int));
class_addIvar(newClass, "_weight", 4, 1, @encode(int));
// 动态添加方法
class_addMethod(newClass, @selector(run), (IMP)run, "v@:");
    
// 注册类
objc_registerClassPair(newClass);
    
id dog = [[newClass alloc] init];
[dog setValue:@10 forKey:@"_age"];
[dog setValue:@20 forKey:@"_weight"];
[dog run];
    
NSLog(@"%@ %@", [dog valueForKey:@"_age"], [dog valueForKey:@"_weight"]);
    
// 在不需要的时候释放
dog = nil; //需要先释放示例对象
objc_disposeClassPair(newClass); //注销类

执行结果:

3.2 示例2

@interface ZSXPerson : NSObject

@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;

@end
// 获取成员变量信息
Ivar ageIvar = class_getInstanceVariable([ZSXPerson class], "_age");
NSLog(@"%s %s", ivar_getName(ageIvar), ivar_getTypeEncoding(ageIvar));
    
// 设置和获取成员变量的值
Ivar nameIvar = class_getInstanceVariable([ZSXPerson class], "_name");
    
ZSXPerson *person = [[ZSXPerson alloc] init];
object_setIvar(person, nameIvar, @"123");
//        object_setIvar(person, ageIvar, @10); //不能直接这样设置
object_setIvar(person, ageIvar, (__bridge id)(void *)10); //需要转成指针变量
    
NSLog(@"%@ %d", person.name, person.age);

执行结果:

3.3 示例3

@interface ZSXPerson : NSObject

@property (nonatomic, assign) int age;
@property (nonatomic, copy) NSString *name;

@end
// 成员列表数量
unsigned int count;
Ivar *ivars = class_copyIvarList([ZSXPerson class], &count);
// 遍历打印成员变量
for (int i = 0; i < count; i++) {
    // 取出 i 位置的成员变量
    Ivar ivar = ivars[i];
    NSLog(@"%s %s", ivar_getName(ivar), ivar_getTypeEncoding(ivar));
}

执行结果:

@oubijiexi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1551973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 进程信号:产生信号

目录 一、通过终端按键产生信号 1、signal()函数 2、核心转储 3、ulmit命令 二、调用系统函数向进程发信号 1、kill()函数 2、raise()函数 3、abort()函数 三、发送信号的过程 读端关闭、写端继续写入的情况 如何理解软件条件给进程发送信号: 四、软件条件产生信…

【Java - 框架 - Lombok】(1) 普通Java项目通过Lombok+Logback完成日志的创建使用 - 快速上手

普通Java项目通过"Lombok""Logback"完成日志的创建使用 - 快速上手&#xff1b; 步骤A 说明 创建"Maven"项目&#xff1b; 图片 步骤B 说明 添加相关依赖项&#xff1b; 图片 代码 <!-- "Lombok"依赖项--> <dependency>&…

Exception in thread “main“ com.fasterxml.jackson.databind.JsonMappingException:

问题&#xff1a;jaskson反序列化超出最大长度 Caused by: com.fasterxml.jackson.core.exc.StreamConstraintsException: String length (5043456) exceeds the maximum length (5000000) 场景&#xff1a;前端传递过大base64 原因&#xff1a; jaskon默认已经限制了最大长…

在Windows系统上安装多个 Nodejs

前言 在Windows系统安装Nodejs 在Windows系统上安装多个 Nodejs v14.16.1安装位置 D:\sde\nodejs\node-v14.16.1-win-x64 v16.20.2安装位置 D:\sde\nodejs\node-v16.20.2-win-x64 v18.20.0安装位置 D:\sde\nodejs\node-v18.20.0-win-x64 v20.12.0安装位置 D:\sde\nod…

TTS 文本转语音模型综合简述

本文参考文献&#xff1a; [1] Kaur N, Singh P. Conventional and contemporary approaches used in text ot speech synthesis: A review[J]. Artificial Intelligence Review, 2023, 56(7): 5837-5880. [2] TTS | 一文了解语音合成经典论文/最新语音合成论文篇【20240111更新…

螺旋矩阵的算法刷题

螺旋矩阵的算法刷题 本文主要涉及螺旋矩阵的算法 包括三个题目分别是 59. 螺旋矩阵 II54. 螺旋矩阵 中等LCR 146. 螺旋遍历二维数组 文章目录 螺旋矩阵的算法刷题一 、螺旋矩阵简单1.1 实现一&#xff08;我认为这个方法更巧妙&#xff01;&#xff01;&#xff09;1.2 实现二&…

谷歌seo外推是什么?

​针对谷歌&#xff0c;站外推广是个不可忽视的环节&#xff0c;外推&#xff0c;也就是站外推广&#xff0c;就是所有在你的网站之外发生的活动&#xff0c;都是为了提升你的品牌在谷歌搜索结果中的排名&#xff0c;但其实本质依旧是外链&#xff0c;也就是指向你网站的链接&a…

【JavaScript】数组 ② ( JavaScript 数组索引 | JavaScript 遍历数组 | 使用 for 循环遍历数组 )

文章目录 一、JavaScript 数组索引1、数组索引2、数组索引 - 代码示例 二、JavaScript 遍历数组1、使用 for 循环遍历数组2、使用 for 循环遍历数组 - 代码示例 一、JavaScript 数组索引 1、数组索引 在 JavaScript 中 , 数组 的 " 索引 " 又称为 " 下标 "…

NVIDIA H200 创下 MLPerf LLM 最新推理记录

NVIDIA H200 Tensor Core GPU 和 NVIDIA TensorRT-LLM 创下 MLPerf LLM 最新推理记录 生成式人工智能正在解锁新的计算应用程序&#xff0c;通过持续的模型创新来极大地增强人类的能力。 生成式 AI 模型&#xff08;包括大型语言模型 (LLM)&#xff09;用于制作营销文案、编写计…

NOIP,CSP-J,CSP-S——树

一、树 概念: 节点、深度、路径、边 树的直径 真题: 答案:B 答案:A 一个树的边是n-1 现在是m,所以m-(n-1)=m-n+1

C++基础11:模板与命名空间

此专栏为移动机器人知识体系下的编程语言中的 C {\rm C} C从入门到深入的专栏&#xff0c;参考书籍&#xff1a;《深入浅出 C {\rm C} C》(马晓锐)和《从 C {\rm C} C到 C {\rm C} C精通面向对象编程》(曾凡锋等)。 10.模板与命名空间 10.1 模板简述 模板使函数和类的处理对象…

Hbase 王者荣耀数据表 HBase常用Shell命令

大数据课本&#xff1a; HBase常用Shell命令 在使用具体的Shell命令操作HBase数据之前&#xff0c;需要首先启动Hadoop&#xff0c;然后再启动HBase&#xff0c;并且启动HBase Shell&#xff0c;进入Shell命令提示符状态&#xff0c;具体命令如下&#xff1a; $ cd /usr/local…

13.软件测试过程与管理

重点&#xff1a; 软件测试的成本管理&#xff1a;区分一致性成本和非一致性成本&#xff1b;根据题干描述计算质量成本、投资回报率&#xff1b; DDP&#xff1a;缺陷探测率的计算&#xff1b;下午题考的频率高&#xff1b; 主要议题&#xff1a; 1.软件测试过程 2.软件测试…

教育建筑智慧能源管理平台解决方案【新型电力系统下的绿色校园能源管理平台】

一、行业特点 1.建筑类型多&#xff1a;集教学、科研、生活于一体&#xff0c;占地面积大&#xff0c;建筑类型多&#xff0c;功能划分复杂。 2.供电可靠性要求高&#xff1a;教育建筑中的高层建筑、图书馆、实验楼等特级和一级负荷比较多&#xff0c;一旦发生故障会危及生命…

【IP 组播】PIM-SM

目录 原理概述 实验目的 实验内容 实验拓扑 1.基本配置 2.配置IGP 3.配置PIM-SM 4.用户端DR与组播源端DR 5.从RPT切换到SPT 6.配置PIM-Silent接口 原理概述 PIM-SM 是一种基于Group-Shared Tree 的组播路由协议&#xff0c;与 PIM-DM 不同&#xff0c;它适合于组播组成…

C++模板类和模板函数

模板类 #include<bits/stdc.h> using namespace std; template<typename T> class People{public:People(T name):name_(name){}protected:T name_; }; class A:public People<string>{public:A(string name): People(name){}void print(){std::cout<<…

启动性能优化

一、应用启动慢的原因 1.在主线程执行了太多耗时的操作&#xff0c;比如加载数据&#xff0c;或者初始化三方库等等&#xff0c;导致在Application的oncreate或者Activity的oncreate方法中耗时太久 2.布局嵌套太深&#xff0c;或者一些不会立即使用的布局也在一开始一起加载到…

tomcat配置静态资源后无法正常访问

目录 一、场景二、配置三、访问异常四、排查五、原因六、解决 一、场景 1、将前端文件存在到指定目录 2、在tomcat配置静态资源 3、配置后无法正常访问到前端文件 二、配置 1、tomcat配置 2、静态资源 三、访问异常 四、排查 可以ping通&#xff0c;但是访问不了3080端口 …

4G CAT.1单灯控制器 计讯物联TL112

传统的照明控制方式往往需要通过开关进行操作&#xff0c;而单灯控制器的出现改变了这一局面。计讯物联单灯控制器TL112&#xff0c;一种基于无线通信技术的智能照明控制设备&#xff0c;可通过管理中心平台、pc电脑端、手机端等多方式&#xff0c;实现对路灯的智能控制&#x…