简单的实用iOS运行时
2016-05-30 09:42
465 查看
objective - c语言尽可能许多决定推迟时间运行时编译时间和链接。只要有可能,它动态地事情。这意味着语言需要的不仅仅是一个编译器,但也一个运行时系统来执行编译后的代码。运行时系统作为一种操作系统的objective - c语言;这就是使语言文字工作。本文着眼于NSObject类和objective - c程序如何与运行时系统交互。特别是,它检查在运行时动态加载新类的范例,并将消息转发给其他对象。它还提供了关于如何找到信息对象的信息,而您的程序正在运行。 —来自苹果官方文档
2.动态创建方法
3.动态交换两个方法
4.在一个类运行的时候,动态的替换掉该类的方法
5.实现归档和反归档
// 字典转模型
}
归档
}
反归档
应用场景
1.遍历属性unsigned int count = 0; Ivar *ivar = class_copyIvarList([self.person class], &count); for (int i = 0; i<count; i++) { Ivar var = ivar[i]; const char *varName = ivar_getName(var); NSString *proname = [NSString stringWithUTF8String:varName]; if ([proname isEqualToString:@"_name"]) { //这里别忘了给属性加下划线 object_setIvar(self.person, var, @"daming"); break; } }
2.动态创建方法
- (void)sayFrom { class_addMethod([self.person class], @selector(guess), (IMP)guessAnswer, "v@:"); if ([self.person respondsToSelector:@selector(guess)]) { //Method method = class_getInstanceMethod([self.xiaoMing class], @selector(guess)); [self.person performSelector:@selector(guess)]; } else{ NSLog(@"Sorry,I don't know"); } self.textview.text = @"beijing"; } void guessAnswer(id self,SEL _cmd){ NSLog(@"i am from beijing"); }
3.动态交换两个方法
Method m1 = class_getInstanceMethod([self.person class], @selector(sayName)); Method m2 = class_getInstanceMethod([self.person class], @selector(saySex)); method_exchangeImplementations(m1, m2);
4.在一个类运行的时候,动态的替换掉该类的方法
Method m1 = class_getInstanceMethod([Person class], @selector(sayName)); Method m2 = class_getInstanceMethod([Tool class], @selector(changeMethod)); method_exchangeImplementations(m1, m2);
5.实现归档和反归档
// 字典转模型
+ (instancetype)objectWithDict:(NSDictionary *)dict { // 创建对应模型对象 id objc = [[self alloc] init]; unsigned int count = 0; // 1.获取成员属性数组 Ivar *ivarList = class_copyIvarList(self, &count); // 2.遍历所有的成员属性名,一个一个去字典中取出对应的value给模型属性赋值 for (int i = 0; i < count; i++) { // 2.1 获取成员属性 Ivar ivar = ivarList[i]; // 2.2 获取成员属性名 C -> OC 字符串 NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; // 2.3 _成员属性名 => 字典key NSString *key = [ivarName substringFromIndex:1]; // 2.4 去字典中取出对应value给模型属性赋值 id value = dict[key]; // 获取成员属性类型 NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; // 二级转换,字典中还有字典,也需要把对应字典转换成模型 // // 判断下value,是不是字典 if ([value isKindOfClass:[NSDictionary class]] && ![ivarType containsString:@"NS"]) { // 是字典对象,并且属性名对应类型是自定义类型 // user User // 处理类型字符串 @\"User\" -> User ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""]; ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""]; // 自定义对象,并且值是字典 // value:user字典 -> User模型 // 获取模型(user)类对象 Class modalClass = NSClassFromString(ivarType); // 字典转模型 if (modalClass) { // 字典转模型 user value = [modalClass objectWithDict:value]; } // 字典,user // NSLog(@"%@",key); } // 三级转换:NSArray中也是字典,把数组中的字典转换成模型. // 判断值是否是数组 if ([value isKindOfClass:[NSArray class]]) { // 判断对应类有没有实现字典数组转模型数组的协议 if ([self respondsToSelector:@selector(arrayContainModelClass)]) { // 转换成id类型,就能调用任何对象的方法 id idSelf = self; // 获取数组中字典对应的模型 NSString *type = [idSelf arrayContainModelClass][key]; // 生成模型 Class classModel = NSClassFromString(type); NSMutableArray *arrM = [NSMutableArray array]; // 遍历字典数组,生成模型数组 for (NSDictionary *dict in value) { // 字典转模型 id model = [classModel objectWithDict:dict]; [arrM addObject:model]; } // 把模型数组赋值给value value = arrM; } } // 2.5 KVC字典转模型 if (value) { [objc setValue:value forKey:key]; } } // 返回对象 return objc;
}
归档
- (void)encodeWithCoder:(NSCoder *)encoder { unsigned int count = 0; Ivar *ivars = class_copyIvarList([Movie class], &count); for (int i = 0; i<count; i++) { // 取出i位置对应的成员变量 Ivar ivar = ivars[i]; // 查看成员变量 const char *name = ivar_getName(ivar); // 归档 NSString *key = [NSString stringWithUTF8String:name]; id value = [self valueForKey:key]; [encoder encodeObject:value forKey:key]; } free(ivars);
}
反归档
- (id)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { unsigned int count = 0; Ivar *ivars = class_copyIvarList([Movie class], &count); for (int i = 0; i<count; i++) { // 取出i位置对应的成员变量 Ivar ivar = ivars[i]; // 查看成员变量 const char *name = ivar_getName(ivar); // 归档 NSString *key = [NSString stringWithUTF8String:name]; id value = [decoder decodeObjectForKey:key]; // 设置到成员变量身上 [self setValue:value forKey:key]; } free(ivars); } return self; }
总结:
详情请转至 https://github.com/WM520/runtime-API相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结
- iOS应用中UISearchDisplayController搜索效果的用法
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- iOS中UIAlertView警告框组件的使用教程
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解