iOS runtime使用

2018-09-12  本文已影响0人  罗马危机

1. 发送消息

objc_msgSend(obj, @selector(func));   调用实例方法

objc_msgSend([Obj class], @selector(func)); 调用类方法

2.交换方法

// 加载内存时调用

+ (void)load

{

  // 获取 ImageOriginalWithStrName: 方法

MethodmyImageName =class_getClassMethod(self,@selector(myImageNamed:));

  // 获取 imageName 方法

MethodimageName =class_getClassMethod(self,@selector(imageNamed:));

  // 交换方法地址, 相当于交换实现

  method_exchangeImplementations(myImageName, imageName);

}

+ (id)myImageNamed:(NSString*)name

{

  UIImage *image = [[self  myImageName:name] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

if(image ==nil) {

NSLog(@"我自己的操作");

  }

returnimage;

}

3.动态添加方法

[self performSelector:@selector(test)];

void test (id self, SEL sel){

  NSLog(@"--- ");

}

/*

 当一个对象调用未实现的方法,会调用+ (BOOL)resolveInstanceMethod:(SEL)sel

 这个方法处理,并且会把这个对应方法列表传过来

 所以动态添加方法, 我们可以在这里做判断, 为我们未实现的方法动态添加自己的方法.

 */

+(BOOL)resolveInstanceMethod:(SEL)sel{

 if (sel == NSSelectorFromString(@"test1")) {

 // <#__unsafe_unretained Class cls#> 参数1 给哪个类添加方法

 // <#SEL name#>  参数2 添加哪个方法

 // <#IMP imp#> 参数3 添加方法函数实现 (函数地址)

 // <#const char *types#> 参数4 函数的类型 (返回值 + 参数类型) v:void @:对象-> self :表示SEL -> _cmd

 class_addMethod(self, sel, (IMP)test1, "v@:@");

 return YES;

 }

 return [super resolveInstanceMethod:sel];

}

4.给分类添加属性

@interface NSObject (ObjName)

@property (nonatomic, strong) NSString *name; // 添加一个name属性

@end

#import 

static const char *key = "name";

@implementation NSObject (ObjName)

- (NSString *)name{

// 根据关联的key,获取关联的值

 return objc_getAssociatedObject(self, key);

}

- (void)setName:(NSString *)name{

 // 参数1 id object 给那个对象添加关联

 // 参数2 const void *key 关联的key 值,通过这个key 值获取

 // 参数3 id value 关联的value

 // 参数4 objc_AssociationPolicy policy 关联的策略

 objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_COPY_NONATOMIC);

}

@end

5.模型转换

- (instancetype)initWithDict:(NSDictionary *)dict

{

 self = [super init];

 if (self)

 {

 // 获取类的属性及属性对应的类型

 NSMutableArray *keys = [NSMutableArray array];

 unsigned int outCount;

 objc_property_t *properties = class_copyPropertyList([self class], &outCount);

 for (int i = 0; i < outCount; i ++)

 {

 objc_property_t property = properties[i];

 // 通过property_getName函数获得属性的名字

 NSString *propertyName = [NSStringstringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];

 [keys addObject:propertyName];

 }

 // 立即释放properties指向的内存

 free(properties);

 // 根据类型给属性赋值

 NSLog(@"+++%@",keys);

 for (NSString *key in keys)

 {

 id value = [dict valueForKey:key];

 if (value == nil)

 {

 continue;

 }

 [self setValue:value forKey:key];

 }

 }

 return self;

}

6.归档、解档

//归档- (void)encodeWithCoder:(NSCoder*)aCoder

{    unsigned int count = 0;

    Ivar* ivars = class_copyIvarList([self class], &count);

    for (int i = 0; i < count; i++) { Ivar ivar = ivars[i]; const char* name = ivar_getName(ivar); NSString* key = [NSString stringWithUTF8String:name];

        [aCoder encodeObject:[self valueForKey:key] forKey :key];

    }

    free(ivars);

}//解档- (id)initWithCoder:(NSCoder*)aDecoder

{    if (self == [superinit]) { unsigned int count = 0; Ivar* ivars = class_copyIvarList([selfclass], &count); for (int i = 0; i < count; i++) { Ivar ivar = ivars[i]; const char* name = ivar_getName(ivar); NSString* key = [NSStringstringWithUTF8String:name]; id value =  [aDecoder decodeObjectForKey:key];//根据key拿到value [self setValue:value forKey:key];//KVC赋值 } free(ivars);    }return self;

}

上一篇下一篇

猜你喜欢

热点阅读