#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