OC runtime 笔记 NSCopying协议
2016-09-26 本文已影响80人
cry_0416
执行方法/通过字符串获得SEL
performSelector:
可绕过编译器,执行没在接口里面的方法
NSSelectorFromString
返回值(SEL) 将一个字符串 -> 方法
给类添加实例变量
可以动态给类添加实例变量
//添加
objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, objc_AssociationPolicy policy)
objc_setAssociatedObject(self, cKey, value, OBJC_ASSOCIATION_COPY)
//取值
objc_getAssociatedObject(<#id object#>, <#const void *key#>)
objc_getAssociatedObject(self, cKey);
KVC 批量化赋值
获取一个类的所有实例变量
#import <objc/objc-runtime.h>
class_copyIvarList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
获取一个类的所有实例变量(返回一个数组,类型是Ivar)
参数1:Class -> 例: [self class]
参数2: counts -> 记录实例变量个数 //传进去的值为 0
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i<count; i++) {
const char *cKey = ivar_getName(ivars[i]);
//实例变量key
NSString *ocInstanceKey = [NSString stringWithCString:cKey encoding:NSUTF8StringEncoding];
//编码key
NSString *coderKey = [@"k" stringByAppendingString:ocInstanceKey];
callback(ocInstanceKey,coderKey);
}
交换两个方法的实现(IMP)
实例方法-SEL和IMP
Method A = class_getClassMethod([self class], @selector(demofunA));
Method B = class_getClassMethod([self class], @selector(demofunB));
method_exchangeImplementations(A, B);
NSCopying协议
@interface Animal ()<NSCopying>
@end
@implementation Animal
- (id)copyWithZone:(NSZone *)zone{
Animal *animal_copy = [[self class]allocWithZone:zone];
animal_copy.name = self.name;
animal_copy.age = self.age ;
// animal_copy.cat = self.cat;
animal_copy.dog = [self.dog copy];
return animal_copy;
}
@end
objc_msgSend(消息发送)
void (*action)(id, SEL) = (void (*)(id, SEL))objc_msgSend;
action(person,NSSelectorFromString(@"eat"));
在objc动态编译时,会被转意为objc_msgSend(per,@selector(eat)
;
其中,void (*action)(id, SEL*)
定义了一个函数指针action,函数的输入值为(id, SEL)
(如果带参数,则在SEL后加)。(void (*)(id, SEL))objc_msgSend
则将objc_msgSend转换为相应的函数指针,并赋值给action。