runtime基础

来源:互联网 发布:java 安卓 编辑:程序博客网 时间:2024/06/09 18:29

runtime   

1、runtime是一套由C语言Api组成的runtime的库。

2、runtime会尽量把代码的执行决策推迟到运行时。

3、OC是动态语言,最后代码都会转换成runtime代码。

runtime的使用场景

1、动态的创建和获取类

2、动态为一个类添加属性和方法

3、在程序运行时遍历类中的成员变量,属性或方法

4、可以调换两个方法的逻辑实现

使用时一定要注意一定要引入<objc/runtime.h>

这里还需要注意的一点是:需要把 图中的这一选项设置为NO


#import "LTRunTimeViewController.h"

#import <objc/runtime.h>

#import <objc/message.h>

#import "LTRunTime.h"


@interface LTRunTimeViewController ()


@end


@implementation LTRunTimeViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view.

        [selftraversalInstanceVariables];

        [selftraversalAttributes];

        [selftraversalTargetMethod];

}


#pragma mark 动态创建类

- (void)createClass

{

    //创建一个类,继承NSObject

    Class MyClass = objc_allocateClassPair([NSObjectclass], "myclass",0);

    

    //添加一个NSString的变量,第四个参数是对其方式,第五个参数是参数类型

    if (class_addIvar(MyClass,"itest", sizeof(NSString *),0, "@")) {

        NSLog(@"add ivar success");

    }

    

    //添加属性一个属性相关项的配置

    objc_property_attribute_t type = {"T", "@\"NSString\"" };//Ttype

    objc_property_attribute_t ownership = {"C", "" };// C = copy

    objc_property_attribute_t backingivar  = {"V", "_privateName" };//variable name

    objc_property_attribute_t attrs[] = { type, ownership, backingivar };

    class_addProperty(MyClass,"privateName", attrs, 3);

    

    //myclasstest是已经实现的函数,"v@:"这种写法见参数类型连接

    class_addMethod(MyClass,@selector(myclasstest:), (IMP)myclasstest,"v@:@");

    class_addMethod(MyClass,@selector(name), (IMP)nameGetter,"@@:");

    

    //注册这个类到runtime系统中就可以使用他了

    objc_registerClassPair(MyClass);

    //生成了一个实例化对象

    id myobj = [[MyClassalloc] init];

    NSString *str =@"asdb";

    //给刚刚添加的变量赋值

    //    object_setInstanceVariable(myobj, "itest", (void *)&str);ARC下不允许使用

    [myobj setValue:strforKey:@"itest"];

    //调用myclasstest方法,也就是给myobj这个接受者发送myclasstest这个消息

    [myobj myclasstest:10];

}


NSString *nameGetter(idself, SEL_cmd) {

    Ivar ivar =class_getInstanceVariable([selfclass], "_privateName");

    returnobject_getIvar(self, ivar);

}


//这个方法实际上没有被调用,但是必须实现否则不会调用下面的方法

- (void)myclasstest:(int)a

{

    

}


//调用的是这个方法

static void myclasstest(idself, SEL _cmd,int a) //self_cmd是必须的,在之后可以随意添加其他参数

{

    Ivar v =class_getInstanceVariable([selfclass], "itest");

    //返回名为itestivar的变量的值

    id o =object_getIvar(self, v);

    //成功打印出结果

    NSLog(@"%@", o);

    NSLog(@"int a is %d", a);

}


#pragma mark 遍历实例变量

-(void)traversalInstanceVariables{

    LTRunTime *person = [[LTRunTimealloc]init];

    NSLog(@"所属的类%@",[personclass]);

    

    Class personClass = person.class;

    unsignedint outCount;

    

    //遍历实例变量

    Ivar *ivarPtr =class_copyIvarList(personClass, &outCount);

    for (NSInteger i =0; i< outCount ; i++) {

        Ivar ivar = ivarPtr[i];

        NSLog(@"ivar实例变量: %s",ivar_getName(ivar));

    }

}


#pragma 遍历属性

-(void)traversalAttributes {

    LTRunTime *person = [[LTRunTimealloc]init];

    NSLog(@"所属的类%@",[personclass]);

    

    Class personClass = person.class;

    unsignedint outCount;

    

    objc_property_t *propertyPtr =class_copyPropertyList(personClass, &outCount);

    for (NSInteger i =0; i < outCount ; i++) {

        objc_property_t t  = propertyPtr[i];

        NSLog(@"属性的名称 %s",property_getName(t));

    }

}


#pragma mark 遍历对象方法

-(void)traversalTargetMethod {

    LTRunTime *person = [[LTRunTimealloc]init];

    NSLog(@"所属的类%@",[personclass]);

    

    Class personClass = person.class;

    unsignedint outCount;

    

    Method *methods =class_copyMethodList(personClass, &outCount);

    for (NSInteger i =0; i < outCount; i++) {

        Method method =methods[i];

        SEL selector =method_getName(method);

        NSLog(@"%@",NSStringFromSelector(selector));

    }

    [person setHeight:@"10"];

    objc_msgSend(person,@selector(dowork));

}


- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}









0 0