Runtime个别API的使用
Runtime 关于属性部分API的说明以及使用方法
使用Runtime机制需要引入头文件:
#import <objc/runtime.h>
1: Ivar *class_copyIvarList(Class cls, unsigned int *outCount)
作用:
复制一个类中的所有属性(私有属性, 公开属性),并返回一个列表
使用方法:
unsigned int outCount; // 声明无符号整型变量
Ivar *ivars = class_copyIvarList([self class], &outCount); // [self class] 您要查询的类,如果查询的是当前使用的类 那么[self class] , 如果是一个对象例如:UserModel *userModel = [UserModel new]; 如果我们查询对象userModel中的属性列表,可以是使用[userModel class]; &outCount 这里是获取 outCount的指针,并给变量 outCount 赋值, 返回值 ivars 这里得到的是 Ivar 类型的集合
if (outCount > 0) {
for (int i = 0; i < outCount; i ++) {
Ivar ivar = ivars[i];
NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)]; // 这里是获取我们定义的属性名称,并转化为字符串对象格式是实例变量的格式:_变量名 , 也就是:带下划线+属性名称例如userModel有一个字符串属性name,那么 key 的值为 _name
}
}
区别: objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
@interface ViewController : UIViewController
{
NSString *descriptionName;
}
@property(nonatomic , copy) NSString *names;
@property (nonatomic , assign) float floatNum;
@end
objc_property_t *objc_property = class_copyPropertyList([self class], &outCount);
NSLog(@"outCount is %u" , objc_property);
打印结果: 2
说明: class_copyPropertyList 这个方法无法获取到实例变量 descriptionName,只能获取到成员变量(@property 声明的变量)
Ivar *ivarsNew = class_copyIvarList([self class], &outCount);
NSLog(@"outCount is %u" , ivarsNew);
打印结果: 3 class_copyIvarList 这个方法可以获取到类中的所有变量不管成员变量还是实例变量
2: const char *ivar_getName(Ivar v)
作用:
通过 Ivar 获取属性名称,返回类型 char 类型,通过 [NSString stringWithUTF8String:ivar_getName(ivar)]方法可以转化为字符串类型
使用方法:
必须获取到属性的 Ivar 指针
方式1:
可以通过 class_copyIvarList(Class cls, unsigned int *outCount) 方法获取 Ivar 的列表集合
例如:
unsigned int outCount; // 声明无符号整型变量
Ivar *ivars = class_copyIvarList([self class], &outCount); // 假如 self 中的第一个属性名称为 name
Ivar ivar = ivars[0]; // 获取属性列表中的首个
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
NSLog(propertyName);
打印结果: _name
方式2:
可以通过 Ivar class_getInstanceVariable(Class cls, const char *name) 方法直接获取 Ivar
UserModel *userModel = [UserModel new]; // 假如 userModel 中有一个 name 的属性,这里我们不用管属性的类型
Ivar ivar = class_getInstanceVariable([userModel class], [@"_name" UTF8String]); // 假如 self 中有名称为name的属性
if (ivar) { // 如果有名称为 name 的属性那么 ivar 不为空
NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)];
NSLog(propertyName);
打印结果: _name
}
3: Ivar class_getInstanceVariable(Class cls, const char *name)
作用:
获取一个类中某个属性的 Ivar
使用方法:
UserModel *userModel = [UserModel new]; // 假如 userModel 中有一个 name 的属性,这里我们不用管属性的类型
Ivar ivar = class_getInstanceVariable([userModel class], [@"_name" UTF8String]); // 属性1: 你要查询的类, 属性2: 实例变量(格式:_属性名)的字符类型
if (ivar) {
// 如果 userModel 类中有属性名称name的属性,可以在下面处理
}
4: const char *ivar_getTypeEncoding(Ivar v)
作用:
获取属性的类型
使用方法:
UserModel *userModel = [UserModel new]; // 假如 userModel 中有一个 name 的属性,类型 NSString
Ivar ivar = class_getInstanceVariable([userModel class], [@"_name" UTF8String]);
if (ivar) {
const char *s = ivar_getTypeEncoding(ivarName); // 获取类型的字符集
NSString *key = [NSString stringWithUTF8String:s]; // 将类型的字符集转化为字符串
NSLog(key);
打印结果: NSString
注释:
不同的类型返回值得结果(注意大小写)为下面列表:
NSString: NSString
BOOL: B
NSInteger: q
CGFloat: f
float: f
double: d
int: i
}
5: id object_getIvar(id obj, Ivar ivar)
作用:
获取属性的返回值
强调: 这里只能获取对象类型的属性值,例如属性类型为NSString类型,我们可以获取到他的 value 值, 如果为 int , BOOL , double , NSTimeInterval , CGFloat , float 我们不能通过这个方法获取属性的 value 值,如果使用这个方法会报错
使用方法:
这里创建一个类,有下面一些属性
@interface UserModel : NSObject
@property (nonatomic , copy) NSString *name;
@property (nonatomic , assign) NSInteger age;
@property (nonatomic , assign) double height;
@end
.m文件不用管
在使用 Runtime 机制的类中创建 UserModel 类
UserModel *userModel = [UserModel new];
userModel.name = @"李";
userModel.age = 27;
userModel.height = 180.1;
Ivar ivarName = class_getInstanceVariable([userModel class], [@"_name" UTF8String]); // 获取查询对象的 Ivar 值
id name = object_getIvar(userModel, ivarName); // 属性1: 要查询的对象 , 属性2: 我们要查询的对象中的属性(必须是:对象属性)的 Ivar 值
if (name) { // 如果返回值不为空
NSLog(name);
打印结果: 李
}
// 那么下面使用获取 age 属性的值
Ivar ivarAge = class_getInstanceVariable([userModel class], [@"_name" UTF8String]);
id age = object_getIvar(userModel, ivarAge); // 这里会报错,并且你也无法获取到错误信息,所以如果获取非对象类型的属性值不能使用这个方法
解决方法1:
double myDoubleValue;
object_getInstanceVariable(userModel, [@"_height" UTF8String], (void*)&myDoubleValue);
NSLog(@"%f", myDoubleValue);
注释:
这里是通过运行时的 Ivar object_getInstanceVariable(id obj, const char *name, void **outValue) 方法获取对象属性的 value 值,我们先不管这个方法的能不能使用,首先一点就是,这个方法是C的方法,并且不支持ARC环境,我们现在开发基本上都是在ARC环境下开发,所以ARC的绕过,MRC就不写了,因为我已经不再使用MRC开发了
解决方法2:
通过 valueForKey: 方法获取返回值(这个方法不是运行时方法)
Ivar ivarAge = class_getInstanceVariable([userModel class], [@"_name" UTF8String]); // 获取对象属性的 Ivar 值
NSString *propertyAge = [NSString stringWithFormat:@"%s" , ivar_getName(ivarD)]; // 获取属性的实例变量名称例如: _age
if (propertyAge) {
NSString *valueForKeyPropertyAge = [userModel valueForKey:propertyAge]; // valueForkey 返回值为 id 类型,我们可以统一使用字符串接收,或者使用相应的声明类型,比如int类型: int valueForKeyPropertyAge = [userModel valueForKey:propertyAge];
}
我们也可以不通过运行时的方法获取
NSString *value = [userModel valueForKey:@"_age"]; // 这里我们通过 key 值直接获取对象 userModel 对应属性的 value 值
Runtime个别API的使用的更多相关文章
- Windows Phone 8 - Runtime Location API - 2
原文:Windows Phone 8 - Runtime Location API - 2 在<Windows Phone 8 - Runtime Location API - 1>介绍基 ...
- Windows Phone 8 - Runtime Location API - 1
原文:Windows Phone 8 - Runtime Location API - 1 在Windows Phone里要做Background Service的方式,除了Background Ag ...
- 在 Windows 8、Windows 10 桌面模式下的 .NET Framework 程序中,引用 Windows.Runtime 的 API。
参考:1.https://www.cnblogs.com/webtojs/p/9675956.html 2.http://jennal.com/2016/04/28/using-windows-run ...
- 运行时Runtime的API
const char * class_getName(Class cls); 返回类的名称. Class class_getSuperclass(Class cls); 返回类的超类. Class c ...
- 【iOS】利用Runtime特性做监控
最近在看Object-C运行时特性,其中有一个特别好用的特性叫 Method Swizzling ,可以动态交换函数地址,在应用程序加载的时候,通过运行时特性互换两个函数的地址,不改变原有代码而改变原 ...
- 【笔记】Windows Phone 8开发笔记之API
Windows Phone 8 API一览 Windows Phone 7平台不支持Native语言的开发,这困扰了许多游戏和底层应用的开发者.Windows Phone 8 SDK的推出,改善了这个 ...
- Swift Runtime ?
你肯定也想过 在OC中相信每一个iOS开发都知道Runtime, 现在Swift也更新到4.0版本了,要是你也学习过Swift的话你可能也会想过这样一个问题,OC大家都是到是有动态性的,你能通过run ...
- Runtime系列(二)--Runtime的使用场景
Runtime 理解介绍的文章非常多,我只想讲讲Runtime 可以用在哪里,而我在项目里哪些地方用到了runtime.多以实际使用过程为主,来介绍runtime的使用. * 那么runtime 怎么 ...
- [runtime] MAObjCRuntime
MAObjCRuntime 源码地址:(引入头文件MARTNSObject.h即可,非arc环境下) http://pan.baidu.com/s/1eQ6776U https://github.co ...
随机推荐
- 执行Git命令时出现各种 SSL certificate problem 的解决办法
执行Git命令时出现各种 SSL certificate problem 的解决办法 来源 https://www.cnblogs.com/chenzc/p/5842932.html 比如我在win ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- centos7升级内核至最新
应用背景: 最近在接触docker,其对内核版本要求较高,就连目前使用的centos7.x默认内核版本为3.10.0-xxx,也是刚好满足其最低要求,故借此机会记录一下升级内核的操作步骤. 测试环境: ...
- java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock
原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...
- 《Exception团队》第一次作业:团队亮相
一.项目基本介绍 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 Exception 作业学习目标 深入了解软件思想,强化编程技术 二.正文 1. ...
- js重点--匿名函数
推荐博客:https://www.cnblogs.com/pssp/p/5216668.html 函数是必须要有函数名的,不然没有办法找到它,使用它. 如果没有名字必须要有一个依附体,如:将这个匿名函 ...
- 随机逻辑回归random logistic regression-特征筛选
python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...
- JVM垃圾回收机制概述
JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...
- 基于Python的Webservice开发(一)-简介
之前为了解决Webservice的开发,直接用Python自带的CGI模块挂在IIS上. 但是该方式开发Soap的接口,需要大量的开发,而且安全方面也存在很多问题. 我推荐关于用Python开发Web ...
- CNN的反向传播
在一般的全联接神经网络中,我们通过反向传播算法计算参数的导数.BP 算法本质上可以认为是链式法则在矩阵求导上的运用.但 CNN 中的卷积操作则不再是全联接的形式,因此 CNN 的 BP 算法需要在原始 ...