runtime-对成员变量和属性的操作
- 成员变量
首先我们来看看成员变量在runtime中是什么样的
在runtime中成员变量是一个objc_ivar类型的结构体,结构体定义如下
struct objc_ivar {
char *ivar_name OBJC2_UNAVAILABLE;//成员变量的名字
char *ivar_type OBJC2_UNAVAILABLE;//成员变量的类型
int ivar_offset OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
}
我们利用runtime对成员变量进行操作主要有以下几种:
Ivar *class_copyIvarList(Class cls, unsigned int *outCount) //获取所有成员变量
const char *ivar_getName(Ivar v) //获取某个成员变量的名字
const char *ivar_getTypeEncoding(Ivar v) //获取某个成员变量的类型编码
Ivar class_getInstanceVariable(Class cls, const char *name) //获取某个类中指定名称的成员变量
id object_getIvar(id obj, Ivar ivar) //获取某个对象中的某个成员变量的值
void object_setIvar(id obj, Ivar ivar, id value) //设置某个对象的某个成员变量的值
接下来上代码来使用一下这些函数,首先我们在.h文件中定义一个Person类,并声明一个personGetMessage方法和自定义类方法
personGetMessage方法是打印出对象的信息,自定义类方法就是创建对象并给对象赋值
{
NSString *clan;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) NSNumber *height;
@property (nonatomic, copy) NSString *gender;
- (void)personGetMessage;// 打印出对象的信息
// 创建对象并给对象赋值
+ (Person *)personWithClan:(NSString *)clan name:(NSString *)name age:(NSInteger)age height:(NSNumber *)height gender:(NSString *)gender;
然后是在.m文件中的实现
- (void)personGetMessage {
unsigned int count;
// 参数一:类名 参数二:成员变量的数量
Ivar *ivarList = class_copyIvarList([self class], &count);
for (int i = ; i < count; i ++) {
Ivar ivar = ivarList[i];
// 输出成员变量的名字,类型编码和值
NSLog(@"name = %s, typeEncoding = %s, value = %@",ivar_getName(ivar), ivar_getTypeEncoding(ivar), object_getIvar(self, ivar));
}
}
+ (Person *)personWithClan:(NSString *)clan name:(NSString *)name age:(NSInteger)age height:(NSNumber *)height gender:(NSString *)gender {
Person *person = [[Person alloc] init];
unsigned int count;
Ivar *ivarList = class_copyIvarList(self, &count);// 获取所有成员变量
/**
* 设置某个对象的某个成员变量的值
*
* @param obj#> 要设置的对象 description#>
* @param ivar#> 对象的成员变量 description#>
* @param value#> 成员变量的值 description#>
*/
object_setIvar(person, ivarList[], clan);
object_setIvar(person, ivarList[], name);
object_setIvar(person, ivarList[], @(age));
object_setIvar(person, ivarList[], height);
Ivar ivar = class_getInstanceVariable(self, "_gender");
object_setIvar(person, ivar, gender);
return person;
}
在程序的入口创建Person对象并且调用presonGetMessage方法控制台就会打印出我们创建的person对象的信息
Person *person = [Person personWithClan:@"汉族" name:@"zhangsan" age: height:@ gender:@"male"];
[person personGetMessage];

以上两个方法的实现基本上把成员变量的基本操作函数都使用了一遍,接下来我们看看属性在runtime中是什么样的
- 属性
属性在runtime中的定义如下
/// An opaque type that represents an Objective-C declared property.
typedef struct objc_property *objc_property_t;
/// Defines a property attribute
typedef struct {
const char *name; /**< The name of the attribute */
const char *value; /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;
属性的本质是一个指向objc_property的结构体指针。跟成员变量一样,runtime中一样为属性定义了一系列对属性的操作函数:
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount) //获取所有属性的列表
const char *property_getName(objc_property_t property) //获取某个属性的名字
const char *property_getAttributes(objc_property_t property) //获取属性的特性描述
objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount) //获取所有属性的特性
接下来我们来使用一下上述这些方法,依然还是在Person类中操作
在.h文件中声明一个getAttributeOfproperty的实例方法并在.m文件中实现这个方法
- (void)getAttributeOfproperty
{
unsigned int outCount;
objc_property_t *propertyList = class_copyPropertyList([Person class], &outCount);
for (NSInteger i = ; i < outCount; i ++) {
NSLog(@"属性:%s,它的特性描述:%s",property_getName(propertyList[i]),property_getAttributes(propertyList[i]));// 获取属性列表只会获取有property属性声明的变量
}
}
因为获取属性列表只会获取有property属性声明的变量,所以成员变量clan就获取不到了,以下是这个方法的打印结果

runtime-对成员变量和属性的操作的更多相关文章
- Objective-C Runtime 运行时之二:成员变量与属性(转载)
在前面一篇文章中,我们介绍了Runtime中与类和对象相关的内容,从这章开始,我们将讨论类实现细节相关的内容,主要包括类中成员变量,属性,方法,协议与分类的实现. 本章的主要内容将聚集在Runtime ...
- Runtime之成员变量&属性&关联对象
上篇介绍了Runtime类和对象的相关知识点,在4.5和4.6小节,也介绍了成员变量和属性的一些方法应用.本篇将讨论实现细节的相关内容. 在讨论之前,我们先来介绍一个很冷僻但又很有用的一个关键字:@e ...
- 刨根问底Objective-C Runtime(4)- 成员变量与属性
http://chun.tips/blog/2014/11/08/bao-gen-wen-di-objective[nil]c-runtime(4)[nil]-cheng-yuan-bian-lian ...
- runtime第二部分成员变量和属性
接上一篇 http://www.cnblogs.com/ddavidXu/p/5912306.html 转载来源http://www.jianshu.com/p/6b905584f536 http:/ ...
- Objective-C Runtime 运行时之二:成员变量与属性
类型编码(Type Encoding) 作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起.这种编码方案在其它情况下也是非常有用的 ...
- OC基础成员变量、属性变量、实例方法与类方法
首先,为什么我们要定义一个新类呢?按照我的理解,就是为了抽象出来一个新的东西(也就是类),用来存储更多的数据变量和方法,一切类都直接或间接继承与NSObject. 在类的头文件里我们可以定义成员变量. ...
- C# 成员变量和属性的区别
之前一直在C#中使用这两者, 却一直不知道成员变量和属性还是不一样的两种概念. 不过说不一样, 也不是完全对. 简单举个例子: public class myclass { public string ...
- C++ 通过对象方式 、指针方式两种方式去访问成员变量(属性或者方法)
准备 1.在VS中新建一个项目-Viscal C++ ---常规--空项目 2.建立一个.h的头文件 定义一个类 声明其成员(C#中的属性和方法) #include<iostream> # ...
- iOS 成员变量和属性的区别
一. 成员变量 1.成员变量的作用范围: @public:在任何地方都能直接访问对象的成员变量 @private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法 @p ...
随机推荐
- SQL Server 2016 JSON原生支持实例说明
背景 Microsoft SQL Server 对于数据平台的开发者来说越来越友好.比如已经原生支持XML很多年了,在这个趋势下,如今也能在SQLServer2016中使用内置的JSON.尤其对于一些 ...
- 使用vscode访问和修改远程计算机文件
使用vscode访问和修改远程文件,分三步实现:在远程linux机器上安装rmate:在本地windows上安装openssh:在vscode中安装扩展remote vscode. 1. 在远程lin ...
- java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。
JNA 调用 dll 库时,保错: ///////////////// 通过 JNA 引入 DLL 库 //////////// /** * ID_FprCap.dll 负责指纹的采集, 指纹仪的初始 ...
- android 获取IMSI信息(判断是移动,联通,电信手机卡)
首先我们需要知道手机IMSI号前面3位460是国家,紧接着后面2位00 02是中国移动,01是中国联通,03是中国电信.那么第一步就是先获取手机IMSI号码:代码如下 /** *获取IMSI信息 * ...
- 【FLUENT案例】05:DDPM模型
本例利用FLUENT的DDPM模型对提升管进行模拟. 1 介绍 本案例演示在FLUENT中利用稠密离散相模型(Dense discrete phase model,DDPM)模拟2D提升管.DDPM模 ...
- python学习笔记-import utils报错
今天遇到一个坑爹的问题,查找了半天原因,终于解决了,在此特地记录一下. 运行环境:Windows eclipse 我在eclipse中配置了python的运行环境,在eclipse中编写python代 ...
- 开发管理系统时,安装sqlserver2005问题整理
最近在为单位开发一个综合管理系统.但是由于时间的问题,有时候就把程序带回家进行修改.但是家里有没有环境,就把数据库文件和程序带回家,可是随之问题来了.要重新在家里陪着开发环境,vs2008非常快的就安 ...
- Jquery-UI使用
=创建form对话框弹出登录 首先引入css样式和js. <link rel="stylesheet" href="<%=path%>/css/demo ...
- codevs 1472 体检
题目描述 Description 郑厂长不是正厂长 也不是副厂长 他根本就不是厂长 只是公司的一个码农 郑厂长所在的公司每一年都要组织员工体检,比如量身高体重.测血压之类的,今年也不例外. 这次总共有 ...
- EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射
I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库的主键.外键以及表名和字段的类型等,这就是EF里的默认映射.具体分为: 数据库映射:Code First ...