利用runtime为系统类追加属性、成员变量
来源:互联网 发布:淘宝修改运费模板 编辑:程序博客网 时间:2024/05/21 17:05
首先,第一个问题,
1》runtime实现的机制是什么,怎么用,一般用于干嘛?
runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API。在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者
比如说,下面一个创建对象的方法 :
[[MJPerson alloc] init]
runtime :objc_msgSend(objc_msgSend(“MJPerson” , “alloc”), “init”)
第二个问题
runtime 用来干什么呢??用在那些地方呢?怎么用呢?
runtime是属于OC的底层, 可以进行一些非常底层的操作(用OC是无法现实的, 不好实现)
在程序运行过程中, 动态创建一个类(比如KVO的底层实现)在程序运行过程中, 动态地为某个类添加属性\方法, 修改属性值\方法遍历一个类的所有成员变量(属性)\所有方法例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置! 例如,PYPerson.h的文件如下所示
@interface PYPerson : NSObject@property (nonatomic, assign) int age;@property (nonatomic, assign) int height;@property (nonatomic, copy) NSString *name;@property (nonatomic, assign) int age2;@property (nonatomic, assign) int height2;@property (nonatomic, assign) int age3;@property (nonatomic, assign) int height3;@property (nonatomic, assign) int age4;@property (nonatomic, assign) int height4;@end
而PYPerson.m实现文件的内容如下
#import "PYPerson.h"@implementation PYPerson (void)encodeWithCoder:(NSCoder )encoder { unsigned int count = 0; Ivar ivars = class_copyIvarList([PYPerson 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([PYPerson 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; }@end
这样我们可以看到归档和解档的案例其实是runtime写下的
学习,runtime机制首先要了解下面几个问题
1.相关的头文件和函数
a> 头文件
利用头文件,我们可以查看到runtime中的各个方法!
b> 相关应用
NSCoding(归档和解档, 利用runtime遍历模型对象的所有属性)字典 –> 模型 (利用runtime遍历模型对象的所有属性, 根据属性名从字典中取出对应的值, 设置到模型的属性上)KVO(利用runtime动态产生一个类)用于封装框架(想怎么改就怎么改)这就是我们runtime机制的只要运用方向
c> 相关函数
objc_msgSend : 给对象发送消息class_copyMethodList : 遍历某个类所有的方法class_copyIvarList : 遍历某个类所有的成员变量class_…..这是我们学习runtime必须知道的函数!
2.必备常识
a> Ivar : 成员变量
b> Method : 成员方法
从上面例子中我们看到我们定义的成员变量,如果要是动态创建方法,可以使用Method。
================== 调皮的分割线 ==================
@"这层讲主题的内容:利用runtime为系统类追加属性成员变量
我们的“射鸡湿”呢,设计了如下的cell :(图图图)
放眼望去,敌军寥寥几人,消灭掉他们不费吹灰之力,长得像极了系统的那个叫做 UITableViewCellStyleSubtitle
的cellStyle,只是多了右下角那组奇怪的东东,可你又懒得自定义一个cell,不是么?于是你想:能不能给系统的UITableViewCell添加2个属性成员变量啊,这样就可以很好的实现效果了啦~~ (嘤嘤嘤)。
嗯,可以。下面就开始撸runtime & category代码(什么?还不会category?活该单身汪,汪汪汪!)
首先,CMD+N 创建新文件,这里要创建category(图如下:)
Next
现在会建category了吧!
然后.h文件就是酱紫:
#import <UIKit/UIKit.h>@interface UITableViewCell (RightDownPlugin)//下面两个控件就是敌军的弱点,加上去他们就GG了@property (nonatomic,strong) UIImageView *statusImgV; //状态图@property (nonatomic,strong) UILabel *statusLab; //状态label@end
然后.m就是酱紫了:
#import "UITableViewCell+RightDownPlugin.h"#include <objc/runtime.h>@implementation UITableViewCell (RightDownPlugin)//定义常量 必须是C语言字符串 因为runtime是C语言API,你写其他的语言它不认识啦~~static char *statusImgKey = "statusImgKey";static char *statusLabKey = "statusLabKey";/* 【科普时间 后面会用到】 OBJC_ASSOCIATION_ASSIGN; //assign策略 OBJC_ASSOCIATION_COPY_NONATOMIC; //copy策略 OBJC_ASSOCIATION_RETAIN_NONATOMIC; // retain策略 OBJC_ASSOCIATION_RETAIN; OBJC_ASSOCIATION_COPY; */ /* id object 给哪个对象的属性赋值 const void *key 属性对应的key id value 设置属性值为value objc_AssociationPolicy policy 使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy); */// 然后就需要自定义set和get方法了,因为category默认是不能添加属性的,哈哈哈 以前是加了也没用,现在是加了会报错。- (void)setStatusImgV:(UIImageView *)statusImgV{ objc_setAssociatedObject(self,statusImgKey,statusImgV,OBJC_ASSOCIATION_RETAIN);}- (UIImageView *)statusImgV{ return objc_getAssociatedObject(self, statusImgKey);}// Lab- (void)setStatusLab:(UILabel *)statusLab{ objc_setAssociatedObject(self,statusLabKey,statusLab,OBJC_ASSOCIATION_RETAIN);}- (UILabel *)statusLab{ return objc_getAssociatedObject(self, statusLabKey);}@end
【多么华丽的走位,多了漂亮的击杀,嗯?亲爱的观众朋友们,我就想问一句:还有谁?哈哈哈哈 】 ——逗比小智
- 利用runtime为系统类追加属性、成员变量
- objc之利用runtime为category添加成员变量
- 59.通过 runtime为Category添加属性与成员变量
- runtime 成员变量和属性
- runtime 成员变量和属性变量
- Runtime 创建动态一个类 添加成员变量 属性
- Runtime 运行时:成员变量与属性
- Runtime(二)成员变量与属性
- runtime之属性和成员变量
- Runtime 为分类增加成员变量
- block为什么用copy?利用runtime运行时的objc_方法为分类扩充成员变量
- 利用Runtime为Category添加属性
- 【iOS开发-117】block为什么用copy?利用runtime运行时的objc_方法为分类扩充成员变量
- runtime 获取类的属性,方法,成员变量,以及协议 字典转model 总结
- Objective-C Runtime 运行时(二):成员变量与属性
- Objective-C Runtime 运行时:成员变量(ivars)及属性
- OC学习之Runtime之一成员变量和属性
- iOS runtime实战应用:成员变量和属性
- plist 文件
- 如何打开xshell中的xftp
- FTP4j下载带有中文的文件时 出现乱码解决方案
- 墨托卡投影(Mercator projection)
- Gradle的安装和配置
- 利用runtime为系统类追加属性、成员变量
- MapReduce job.setNumReduceTasks(0)思考
- 平安阿里数据库技术交流日总结
- 【代码笔记】iOS-点击加号增加书架,点击减号减少书架
- 解决:115网盘下载路径失败
- iOS屏幕横竖屏旋转相关
- springmvc jquery 使用时,format中使用fmt的实现
- H264编码 封装成MP4格式 视频流 RTP封包
- 赞扬和批评的黄金比例