Runtime 实练

#import"ViewController.h"

#import"Person.h"

#import

@interfaceViewController ()

@end

@implementationViewController

- (void)viewDidLoad {

[superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

//[self test1];

//[self test2];

//[self test3];

//[self test4];

[selftest5];

}

- (void)test1{

unsignedintcount;

//获取成员变量列表Ivar是一个c结构体指针

Ivar *ivars = class_copyIvarList([Person class],

&count);//需要导入头文件#import

for(inti =0; i < count; i++) {

Ivar ivar = ivars[i];

//根据ivar获得成员变量的名称

constchar*name =

ivar_getName(ivar);

//将c字符串转成OC的字符串

NSString * key = [NSString stringWithUTF8String:name];

NSLog(@"%d = %@",i,key);

//        2016-04-07 13:58:09.290 RunTimeTest[4663:159020] 0 = _age

//        2016-04-07 13:58:09.291 RunTimeTest[4663:159020] 1 = _height

//        2016-04-07 13:58:09.291 RunTimeTest[4663:159020] 2 = _delegate

//        2016-04-07 13:58:09.292 RunTimeTest[4663:159020] 3 = _name

//        2016-04-07 13:58:09.292 RunTimeTest[4663:159020] 4 = _sex

//        2016-04-07 13:58:09.292 RunTimeTest[4663:159020] 5 = _job

//        2016-04-07 13:58:09.293 RunTimeTest[4663:159020] 6 = _native

//        2016-04-07 13:58:09.293 RunTimeTest[4663:159020] 7 =   _education

//可以使用kvc给类的变量赋值

//        [self setValue:@"haha" forKey:key];

}

//记得释放资源

free(ivars);

}

- (void)test2{

unsignedintcount;

//获取类的属性列表objc_property_t也是一个c结构体指针

objc_property_t* propertys =class_copyPropertyList([Personclass], &count);//需要导入头文件#import

for(inti =0; i < count; i++) {

objc_property_tproperty = propertys[i];

//根据ivar获得成员变量的名称

constchar*name =property_getName(property);

//将c字符串转成OC的字符串

NSString* key = [NSStringstringWithUTF8String:name];

NSLog(@"%d = %@",i,key);

//        2016-04-07 13:57:33.301 RunTimeTest[4646:158428] 0 = delegate

//        2016-04-07 13:57:33.302 RunTimeTest[4646:158428] 1 = name

//        2016-04-07 13:57:33.302 RunTimeTest[4646:158428] 2 = sex

//        2016-04-07 13:57:33.302

RunTimeTest[4646:158428] 3 = age

//        2016-04-07 13:57:33.302

RunTimeTest[4646:158428] 4 = height

//        2016-04-07 13:57:33.302 RunTimeTest[4646:158428] 5 = job

//        2016-04-07 13:57:33.303 RunTimeTest[4646:158428] 6 = native

//        2016-04-07 13:57:33.303 RunTimeTest[4646:158428] 7 = education

//可以使用kvc给类的属性赋值

//        [self setValue:@"haha" forKey:key];

}

//记得释放资源

free(propertys);

}

/**获取一个类的全部方法*/

- (void)test3{

unsignedintcount;

//获取指向给类所有方法的指针

Method* methods =class_copyMethodList([Personclass], &count);

for(inti =0; i < count; i++) {

//获取该类的一个方法的指针

Methodmethod =

methods[i];

//获取方法

SELmethodSEL =method_getName(method);

//将方法转成c字符串

constchar* name =sel_getName(methodSEL);

//将c字符串转为OC字符串

NSString* methodName =

[NSStringstringWithUTF8String:name];

//获取方法的参数个数

intarguments =

method_getNumberOfArguments(method);

NSLog(@"%d = %@ , %i ",i,methodName,arguments);

//        2016-04-07 14:22:38.636 RunTimeTest[4912:172247] 0 = test3 , 2

//        2016-04-07 14:22:38.637 RunTimeTest[4912:172247] 1 = eat , 2   //注:因为在.m文件中有eat方法的实现,而没有sleep和work方法的实现,所有打印的时候没有这两个方法

//        2016-04-07 14:22:38.638 RunTimeTest[4912:172247] 2 = test1 , 2

//        2016-04-07 14:22:38.638 RunTimeTest[4912:172247] 3 = test2 , 2

//        2016-04-07 14:22:38.638 RunTimeTest[4912:172247] 4 = sex , 2

//        2016-04-07 14:22:38.638 RunTimeTest[4912:172247] 5 = setSex: , 3

//        2016-04-07 14:22:38.639 RunTimeTest[4912:172247] 6 = age , 2

//        2016-04-07 14:22:38.639 RunTimeTest[4912:172247] 7 = setAge: , 3

//        2016-04-07 14:22:38.639 RunTimeTest[4912:172247] 8 = job , 2

//        2016-04-07 14:22:38.639 RunTimeTest[4912:172247] 9 = setJob: , 3

//        2016-04-07 14:22:38.639 RunTimeTest[4912:172247] 10 = native , 2

//        2016-04-07 14:22:38.640 RunTimeTest[4912:172247] 11 = setNative: , 3

//        2016-04-07 14:22:38.640 RunTimeTest[4912:172247] 12 = education , 2

//        2016-04-07 14:22:38.640 RunTimeTest[4912:172247] 13 = setEducation: , 3

//        2016-04-07 14:22:38.640 RunTimeTest[4912:172247] 14 = .cxx_destruct , 2

//        2016-04-07 14:22:38.641 RunTimeTest[4912:172247] 15 = name , 2

//        2016-04-07 14:22:38.641 RunTimeTest[4912:172247] 16 = setDelegate: , 3

//        2016-04-07 14:22:38.707 RunTimeTest[4912:172247] 17 = setName: , 3

//        2016-04-07 14:22:38.707 RunTimeTest[4912:172247] 18 = delegate , 2

//        2016-04-07 14:22:38.707 RunTimeTest[4912:172247] 19 = init , 2

//        2016-04-07 14:22:38.707 RunTimeTest[4912:172247] 20 = height , 2

//        2016-04-07 14:22:38.708 RunTimeTest[4912:172247] 21 = setHeight: , 3

}

//记得释放资源

free(methods);

}

/**获取一个类遵循的全部协议*/

- (void)test4{

unsignedintcount;

//获取指向该类所遵守的所有协议的指针二级指针

__unsafe_unretainedProtocol **  protocols = class_copyProtocolList([selfclass],

&count);

for(inti =0; i < count; i++) {

//获取该类遵循的一个协议的指针

Protocol *protocol = protocols[i];

//获取c字符串协议名

constchar* name =

protocol_getName(protocol);

//将c字符串转成oc字符串

NSString* protocolName = [NSString

stringWithUTF8String:name];

NSLog(@"%d = %@",i,protocolName);

//        2016-04-07 14:46:10.429 RunTimeTest[5192:187092] 0 = PersonDelegate

}

//记得释放资源

free(protocols);

}

/**

*获取运行时所知道的所有协议列表

*/

- (void)test4_2{

unsignedintcount;

//获取指向该类所遵守的所有协议的指针 二级指针

__unsafe_unretainedProtocol **  protocols =objc_copyProtocolList(&count);

NSLog(@"count2 = %i",count);

for(inti =0; i < count; i++) {

//获取该类遵循的一个协议的指针

Protocol *protocol = protocols[i];

//获取c字符串协议名

constchar* name =protocol_getName(protocol);

//Protocol *protocol2 = objc_getProtocol(name);

//将c字符串转成oc字符串

NSString* protocolName = [NSStringstringWithUTF8String:name];

NSLog(@"%d = %@",i,protocolName);

}

//记得释放资源

free(protocols);

}

/**

*在运行时注册新的协议

*/

- (void)test4_3{

NSString* protocolName =@"TheHaHaDelegate";

//1.创建新的协议实例

Protocol *protocol =objc_allocateProtocol(protocolName.UTF8String);

//2.在运行时中注册新创建的协议

objc_registerProtocol(protocol);

NSString* typeStr =@"Haha";

SELs =NSSelectorFromString(@"testHaHa");

SELs1 =@selector(testHaHa);

Methodm =class_getInstanceMethod([selfclass], s1);

NSString* methodStr =

[NSStringstringWithUTF8String:sel_getName(method_getName(m))];

NSLog(@"methodStr = %@",methodStr);

protocol_addMethodDescription(protocol, s, typeStr.UTF8String,NO,YES);

//[self test4_2];

}

/**利用runtime归档/解档*/

- (void)test5 {

Person* p = [[Person alloc]init];

p.name =@"李世民";

p.sex =@"男";

p.age =29;

p.height =175.9;

p.education =@"本科";

p.job =@"iOS工程师";

p.native =@"湖北";

NSString* path = [NSString

stringWithFormat:@"%@/achive",NSHomeDirectory()];

[NSKeyedArchiver archiveRootObject:p toFile:path];

Person * unarchiverPerson = [NSKeyedUnarchiver

unarchiveObjectWithFile:path];

NSLog(@"p = %@, unarchiverPerson = %@,path = %@",p,unarchiverPerson,path);

//2016-04-07 15:12:33.512 RunTimeTest[5527:202447] p =

0x7fcb4851fc50>, unarchiverPerson = ,path =

/Users/ljh/Library/Developer/CoreSimulator/Devices/42F17580-71DE-4349-AFAD-5DD92E56B5CB/data/Containers/Data/Application/DAAEBF7C-2DF1-4FD3-9F76-8A96E3B50F75/achive

}

@end



#import

@protocolPersonDelegate

- (void)personDelegateToWork;

@end

@interfacePerson :NSObject

@property(assign,nonatomic)id delegate;

@property(nonatomic,copy)NSString* name;

@property(nonatomic,copy)NSString* sex;

@property(nonatomic,assign)intage;

@property(nonatomic,assign)floatheight;

@property(nonatomic,copy)NSString* job;

@property(nonatomic,copy)NSString* native;

@property(nonatomic,copy)NSString* education;

- (void)eat;

- (void)sleep;

- (void)work;

@end


#import"Person.h"

#import

@interfacePerson()

@end

@implementationPerson

- (instancetype)init{

if(self= [superinit]) {

}

returnself;

}

- (void)eat{

}

#pragma mark -实现归档/解档必须实现的方法

- (void)encodeWithCoder:(NSCoder*)aCoder {

unsignedintcount;

//获取类的属性列表  objc_property_t 也是一个 c 结构体指针

objc_property_t* propertys =class_copyPropertyList([Personclass], &count);//需要导入头文件#import

for(inti =0; i < count; i++) {

objc_property_tproperty = propertys[i];

//根据ivar获得成员变量的名称

constchar*name =property_getName(property);

//将c字符串转成OC的字符串

NSString* propertyName = [NSStringstringWithUTF8String:name];

//使用kvc取值

NSString* propertyValue = [selfvalueForKey:propertyName];

//编码属性

[aCoderencodeObject:propertyValueforKey:propertyName];

}

//记得释放资源

free(propertys);

//这样就不用对类中的属性逐个存档了

}

- (instancetype)initWithCoder:(NSCoder*)aDecoder {

unsignedintcount;

//获取类的属性列表  objc_property_t 也是一个 c 结构体指针

objc_property_t* propertys =class_copyPropertyList([Personclass], &count);//需要导入头文件#import

for(inti =0; i < count; i++) {

objc_property_tproperty = propertys[i];

//根据ivar获得成员变量的名称

constchar*name =property_getName(property);

//将c字符串转成OC的字符串

NSString* propertyName = [NSStringstringWithUTF8String:name];

//解码属性值

NSString* propertyValue = [aDecoderdecodeObjectForKey:propertyName];

//使用kvc存值

[selfsetValue:propertyValueforKey:propertyName];

}

//记得释放资源

free(propertys);

//这样就不用对类中的属性逐个解档了

returnself;

}

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容