修改系统方法
//先要导入message类
#import <objc/message.h>
@implementation UIImage (Image)
+(void)load{
//class_getInstanceMethod(<#__unsafe_unretained Class cls#>, <#SEL name#>) 这个是获取对象方法 -
//获取imageNamed 类方法 +
//获取vjimageNamed 类方法 +
Method imageNamedMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));
Method vjimageNamedMethod = class_getClassMethod([UIImage class], @selector(vj_imageNamed:));
//交换两个方法(当调用imageNamed时是调用的vj_imageNamed 反之亦然 注意死循环)
method_exchangeImplementations(imageNamedMethod, vjimageNamedMethod);
}
+(__kindof UIImage*)vj_imageNamed:(NSString*)name{
UIImage *image = [self vj_imageNamed:name];
if (!image) {
NSLog(@"加载为空");
}
return image;
}
@end
动态添加方法
Son *s = [[Son alloc] init];
//发送对象方法消息时会调用类的resolveInstanceMethod
//发送类方法消息时会调用类的resolveClassMethod
[s performSelector:@selector(haha:) withObject:@"hello"];
void hahaIMP(id self,SEL _cmd , id num){
NSLog(@"%@",num);
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
//判断方法编号
if (sel == @selector(haha:)) {
//添加方法,第三个参数是c语言的函数 需要先定义个函数
//第四个参数是c语言函数的参数类型详情见帮助文档搜
//"rumtime->Type Encodings"
class_addMethod(self, sel, (IMP)hahaIMP, "v@:@");
return YES;
}
return [super resolveClassMethod:sel];
}
动态给系统类添加属性(给分类添加属性)
#import "NSObject+objName.h"
#import <objc/message.h>
@implementation NSObject (objName)
//在分类的.h文件中 使用@proterpty只会生成属性的getset声明 不会去实现 也不会定义成员属性 因为分类定义不了属性
//所以要重写getset方法 一个对象属性赋值其实就是 让一个对象里产生一个key关联另一个对象。
- (NSString *)name{
return objc_getAssociatedObject(self, "name");
}
- (void)setName:(NSString *)name{
//第四个参数是关联策略就像定义属性时的(nonatomic,strong)
objc_setAssociatedObject(self, "name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
runtime+kvc 转换模型
+(instancetype)createObjByDictionary:(NSDictionary*)dic{
id obj = [[self alloc] init];
//创建一个无符号整形变量 把地址值给下面方法 下面方法会对该变量进行处理赋值成员属性的个数
unsigned int count = 0;
//返回的是一个ivar数组 声明一个指针变量指向该数组
Ivar *ivarList = class_copyIvarList(self, &count);
for (int i = 0; i<count; i++) {
//从数组中取出该Ivar指针类型的值
//typedef struct objc_ivar *Ivar; Ivar是一个指针类型
Ivar ivar = ivarList[i];
//此处是获取到成员属性
NSString *ivarName = [NSString stringWithUTF8String: ivar_getName(ivar)];
NSString *ivarType = [NSString stringWithUTF8String: ivar_getTypeEncoding(ivar)];
//KVC需要使用属性不是成员属性
ivarName = [ivarName substringFromIndex:1];
id value = dic[ivarName];
//二级转换
//值是字典 并且属性类型不是系统类(排除该属性声明是字典类型)
if ([value isKindOfClass:[NSDictionary class]] && ![ivarType containsString:@"NS"]) {
//把属性类型字符串中的转义符去掉
NSRange range = [ivarType rangeOfString:@"\""];
ivarType = [ivarType substringFromIndex:range.location+range.length];
range = [ivarType rangeOfString:@"\""];
ivarType = [ivarType substringToIndex:range.location];
Class modelClass = NSClassFromString(ivarType);
if (modelClass) {
//给value变量赋值该类型转换后的对象
value = [modelClass createObjByDictionary:value];
}
}
[obj setValue:value forKey:ivarName];
}
return obj;
}
网友评论