Runtime学习笔记(一)——成员变量和属性
2016-03-24 14:46
435 查看
最近开始学习runtime,想挖掘iOS的运行机制,经过几天折腾,终于初窥门径,首先记录关于成员变量和属性的学习内容
1.获取成员变量
Ivar: 实例变量类型,是一个指向objc_ivar结构体的指针
typedef struct objc_ivar *Ivar;
model的声明:
2.获取属性
objc_property_t:声明的属性的类型,是一个指向objc_property结构体的指针
typedef struct objc_property *objc_property_t;
关键代码:
3.获取在.m中声明的变量
4.json转model
首先创建一个NSObject+RunTime的分类
1.获取成员变量
Ivar: 实例变量类型,是一个指向objc_ivar结构体的指针
typedef struct objc_ivar *Ivar;
model的声明:
#import <Foundation/Foundation.h> @interface Model : NSObject { NSString * _string1; } @property NSString * string2; @property (nonatomic, copy) NSDictionary * dict; @end关键代码:
#import "ViewController.h" #import "Model.h" #import <objc/runtime.h> @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //获取成员变量 [self test1]; } -(void)test1{ unsigned int outCount = 0; Ivar * ivars =class_copyIvarList([Model class], &outCount);//获取该类中所有的成员变量 for (unsigned int i = 0; i < outCount; i++) { Ivar ivar = ivars[i]; const char * name = ivar_getName(ivar);//获取成员变量的名称 const char * type = ivar_getTypeEncoding(ivar);//获取成员变量的类型 NSLog(@"类型:%s \n名称:%s ", type, name); } //释放内存 free(ivars); }
2.获取属性
objc_property_t:声明的属性的类型,是一个指向objc_property结构体的指针
typedef struct objc_property *objc_property_t;
关键代码:
-(void)test2{ unsigned int outCount = 0; objc_property_t * properties = class_copyPropertyList([Model class], &outCount); for (unsigned int i = 0; i < outCount; i++) { objc_property_t property = properties[i]; //属性名 const char * name = property_getName(property); //属性描述 const char * propertyAttr = property_getAttributes(property); NSLog(@"属性描述为 %s 的 %s ", propertyAttr, name); //属性的特性 unsigned int attrCount = 0; objc_property_attribute_t * attrs = property_copyAttributeList(property, &attrCount); for (unsigned int j = 0; j < attrCount; j++) { objc_property_attribute_t attr = attrs[j]; const char * name = attr.name; const char * value = attr.value; NSLog(@"属性的描述:%s 值:%s", name, value); } free(attrs); NSLog(@"\n===============\n"); } free(properties); }其他代码同test1。
3.获取在.m中声明的变量
#import "JsonToModelBaseClass.h" @interface JsonToModelBaseClass () { NSString * _string1; } @end @implementation JsonToModelBaseClass @end关键代码:
-(void)test3{ JsonToModelBaseClass * baseModel = [[JsonToModelBaseClass alloc] init]; Ivar ivar = class_getInstanceVariable([baseModel class], "_string1"); NSString * str = object_getIvar(baseModel, ivar); NSLog(@"%@", str); }
4.json转model
首先创建一个NSObject+RunTime的分类
#import <Foundation/Foundation.h> @interface NSObject (RunTime) -(instancetype)initWithDict:(NSDictionary *)dict; @end关键代码
#import "NSObject+RunTime.h" #import <objc/runtime.h> @implementation NSObject (RunTime) -(instancetype)initWithDict:(NSDictionary *)dict { if (self == [self init]) { [self setPropertyWithDict:dict]; } return self; } -(void)setPropertyWithDict:(NSDictionary *)dict{ //(1)获取类的属性及属性对应的类型 NSMutableArray * keyArray = [NSMutableArray array]; NSMutableArray * attributeArray = [NSMutableArray array]; unsigned int outCount = 0; objc_property_t * properties = class_copyPropertyList([self class], &outCount); for (unsigned int i = 0; i < outCount; i++) { objc_property_t property = properties[i]; //通过property_getName函数获得属性的名字 NSString * propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding]; [keyArray addObject:propertyName]; //通过property_getAttributes函数可以获得属性的名字和@encode编码 NSString * propertyAttribute = [NSString stringWithCString:property_getAttributes(property) encoding:NSUTF8StringEncoding]; [attributeArray addObject:propertyAttribute]; } //释放properties free(properties); //(2)根据类型给属性赋值 for (NSString * key in keyArray) { if ([dict valueForKey:key] == nil) { continue; } [self setValue:[dict valueForKey:key] forKey:key]; } }然后创建model声明属性
#import <Foundation/Foundation.h> @interface JsonToModelBaseClass : NSObject @property (nonatomic, copy) NSString * name; @property (nonatomic, copy) NSString * age; @property (nonatomic, copy) NSString * intro; @end实现
-(void)test4{ NSDictionary * dict = @{@"name" : @"xiaoming", @"age" : @"20", @"intro" : @"SB"}; JsonToModelBaseClass * baseModel = [[JsonToModelBaseClass alloc] initWithDict:dict]; NSLog(@"%@", baseModel); }这样就会像KVC一样,直接把json中相应的数据赋值给model.
相关文章推荐
- NSNotificationCenter简单使用
- 关于ocx控件的跨语言使用
- Studio 从入门到精通 (一)
- socket笔记
- 关于Activity无重写方法--菜单项onCreateOptionsMenu
- ArtifactdescriptorException: failed to read artifact for xxxxxx.
- (转)分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)
- 一个完整的创建用户,创建表空间,授权建表过程
- spring 配置多数据源
- WebDriver与文件系统
- MYSQL数据导入导出
- 数据库面试题(更新中。。。)
- Cppcheck 1.54 C/C++静态代码分析工具
- Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
- Latex编辑技巧杂锦
- Java成员内部类
- Unity3D 与android交互流程步骤
- oracle性能优化(一)
- MYSQL数据库管理之权限管理
- C++用钩子模仿按键精灵录制键盘鼠标的功能