iOS 运行时(runtime)浅析
本博客,直接从分类说起.都知道OC中的分类是不能直接添加属性的,意思间接是能添加属性的.那应该怎么添加呢?那就要用到运行时(runtime)机制.
一,运行时金典用法之一
现在,给HGPerson类增加一个分类:HGPerson+HG.h,给一个属性如下:
@property (nonatomic, copy) NSString* name;
貌似,这样写了以后,是能调用的,但是运行就报错了.
-[HGPerson setName:]: unrecognized selector sent to instance 0x7f90b2e13620
2015-10-02 20:41:28.803 Runtime[3357:285701] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[HGPerson setName:]: unrecognized selector sent to instance 0x7f90b2e13620'
意思是没有找到这个方法:-[HGPerson setName:]....哦,我明白了.在分类里面没有实现,所以报错的.
现在开始动用OC的运行时机制了,动态的给一个类添加成员变量.code如下:
#import "HGPerson+HG.h"
#import <objc/message.h>
@implementation HGPerson (HG)
/**
动态的给本类增加一个成员变量
*/
// 这个key是用来参考的<我也不是太明白>,并不是成员变量
static double nameKey;
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name {
return objc_getAssociatedObject(self, &nameKey);
}
@end
二, 运行时的金典用法之二
// 记录HGPerson类中成员变量的数量
NSInteger count;
// 获得HGPerson类中的所有成员变量列表
Ivar* ivars = class_copyIvarList(objc_getClass("HGPerson"), &count);
// 遍历HGPerson类中的成员变量
for (NSInteger i=0; i<count; i++) {
Ivar iavr = ivars[i];
const char* name = ivar_getName(iavr);
const char* type = ivar_getTypeEncoding(iavr);
}