runtime学习

runtime 是什么

  • runtime,运行时机制,它是一套C语言库;
  • 实际上我们编写的所有OC代码,最终都是转成了runtime库的东西,比如类转成了runtime库里面的结构体等数据类型,方法转成了runtime库里面的C语言函数,平时调方法都是转成了objc_msgSend函数(所以说OC有个消息发送机制);
  • 因此,可以说runtime是OC的底层实现,是OC的幕后执行者;

runtime的实现机制是什么

运行时机制,runtime库里面包含了跟类/成员变量/方法相关的API,比如获取类里面的所有成员变量,为类动态添加成员变量,动态改变类的方法实现,为类动态添加新的方法等;

runtime 能做什么

  • 关联对象,动态绑定对象
  • 获取类的所有属性,成员变量,进行其他操作,
  • Method Swizzling,替换类已有函数
  • 动态创建函数

  • 关联对象的简单实现方法
    有时我们需要对一些控件操作,需要传递某个属性,这时使用关联对象就方便多了,看代码
@interface UIView (parameter){
}
-(void)setCustomParame:(NSDictionary*)dic;
-(NSDictionary*)customParame;
@end

//任何继承UIView 的都可以使用传递该参数,方便调用
@implementation UIView (parameter)
static char UIViewParameterKey;

-(void)setCustomParame:(NSDictionary *)dic{
    objc_setAssociatedObject(self, &UIViewParameterKey, dic, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSDictionary*)customParame{
    return objc_getAssociatedObject(self, &UIViewParameterKey);
}

@end

获取类的所有属性,成员变量,进行其他操作,平时使用到的地方有json 转model 的时候,我们需要遍历model 的所有属性,然后进行操作,用的方法class_copyIvarList方法进行遍历,或者归档都可以;

先建一个model 类

@interface User : NSObject{
    NSArray *arry;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *school;
@property(nonatomic,assign) int age;
@property(nonatomic,assign) BOOL sex;
@end

然后利用class_copyIvarList遍历获取,

-(void)testClass_copyIvarList{
    unsigned int count = 0;
    Ivar *ivars=class_copyIvarList([User class], &count);
    for (int i=0; i<count; i++) {
        NSString * str=[NSString stringWithUTF8String:ivar_getName(ivars[i])];
        NSLog(@"testtwo-------%@",str);
    }
    free(ivars);
}

打印结果

copyedString-0xa000000006362613,0xa000000006362613
2016-01-25 23:40:43.813 class_copyIvarlistTEST[2149:378140] testtwo-------arry
2016-01-25 23:40:43.813 class_copyIvarlistTEST[2149:378140] testtwo-------_sex
2016-01-25 23:40:43.813 class_copyIvarlistTEST[2149:378140] testtwo-------_age
2016-01-25 23:40:43.813 class_copyIvarlistTEST[2149:378140] testtwo-------_name
2016-01-25 23:40:43.813 class_copyIvarlistTEST[2149:378140] testtwo-------_school
(lldb) 

还有一个方法class_copyPropertyList是获取所有属性的方法;

Method Swizzling,有method_exchangeImplementations交换2个方法,

@implementation UIScrollView(DataFetch)


+ (void)load
{
    Method dealloc = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc"));
    Method df_dealloc = class_getInstanceMethod([self class], @selector(df_dealloc));
    method_exchangeImplementations(dealloc, df_dealloc);

}

还有替换已有函数class_replaceMethod

void demoReplaceMethod(id SELF, SEL _cmd)
{
    NSLog(@"demoReplaceMethod");
}

-(void)replaceMethod
{
    Class strcls = [self class];
    SEL  targetSelector = @selector(targetRelplacMethod);
    class_replaceMethod(strcls,targetSelector,(IMP)demoReplaceMethod,NULL);
}

-(void)targetRelplacMethod
{
    NSLog(@"targetRelplacMethod");
}
测试
RuntimeObj *obj = [[RuntimeObj alloc]init];
[obj replaceMethod];
[obj targetRelplacMethod];

打印结果
2014-05-12 19:38:37.490 Runtime[1497:303] demoReplaceMethod

是不是原来的  NSLog(@”targetRelplacMethod”); 这句话就没有执行 被替换掉了

class_replaceMethod 方法就是动态替换Method的函数,原型 IMP class_replaceMethod(Class cls, SEL name,IMP imp, const char *types) 返回值就是一个新函数的地址(IMP指针)
在实际项目中会经常用到这种方式 比如:iOS 7以及7以下绘制NavigationBar 自己慢慢体会吧

以上就是简单的rumtime 的使用,方法,其中部分参考了以下文章

http://www.anselz.com/2014/05/12/objective-c-runtime%E8%83%BD%E5%81%9A%E4%BB%80%E4%B9%88%EF%BC%9F/

http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/

你可能感兴趣的:(Runtime)