您的位置:首页 > 其它

Runtime学习笔记(一)——成员变量和属性

2016-03-24 14:46 435 查看
最近开始学习runtime,想挖掘iOS的运行机制,经过几天折腾,终于初窥门径,首先记录关于成员变量和属性的学习内容

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: