RunTime的运行机制简单使用

Runtime 是一套比较底层的纯C语言API 它是OC的幕后工作者 我们平时写的OC代码 ,在运行时都会编译器转为runtime的C语言代码 其中最主要的是消息机制OC的函数调用,成为消息发送 属于动态调用过程 在编译的时候并不能决定真正调用哪个函数事实证明,在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错,而C语言在编译阶段就会报错 只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。

RunTime可以动态的给对象的属性赋值,还可以修改属性;

          简单的运行时

    Class BGCls = NSClassFromString(@"Bigbang");  
    id Top = [[BGCls alloc] init];

    [cat1 performSelector:@selector(setName:) withObject:@"GD"];

    NSLog(@"name:%@",[Top valueForKey:@"name"]);

首先通过obj的isa指针找到obj对应的class。在Class中先去cache中 通过SEL查找对应函数method—cache中method列表是以key通过hash表来存储的,这样能提高函数查找速度),若 cache中未找到。再去methodList中查找,若methodlist中未找到,则取superClass中查找。若能找到,则将method加 入到cache中,以方便下次查找,并通过method中的函数指针跳转到对应的函数中

RunTime可以动态的添加一个类,它会通过类名获取类,如果类不存在就会创建需要运行类父类,我们可以通过指定协议(Protocol)的方式

运行如何添加一个类
    // 设置类名
    const char * className = "MyClass";
    // 通过类名获取类
    Class kclass = objc_getClass(className);
    // 如果类不能存在
    if (!kclass)
    {
        // 创建需要运行类父类
        Class superClass = [NSObject class];

        // 创建类
        kclass = objc_allocateClassPair(superClass, className, 0);
    }



    // 3. 对类添加方法
    IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
        NSLog(@"Hello %@", string);
    });
    // @encode(float) 用这个关键字可以获取 参数类型
    class_addMethod(kclass, @selector(sayHello:), myIMP, "v@:@");

    // 添加成员变量
//    class_addIvar
    // 添加关联属性
//    class_addProperty
    // 添加协议
//    class_addProtocol

    // 注册类
    objc_registerClassPair(kclass);



    // 如何获取内存中所有的OC类

    // 类的数量
    int numClasses;
    // 存放指向第一个类的指针
    Class *classes = NULL;

    // 获取多少类
    numClasses = objc_getClassList(NULL, 0);

    // 如果获取的类大于0
    if(numClasses > 0) {
        // 为获取所有的类开辟内存
        classes = (Class *)malloc(sizeof(Class) * numClasses);

        // 把所有类拷贝到我开的内存中
        numClasses = objc_getClassList(classes, numClasses);
        // 遍历所有的类
        for (NSInteger i = 0; i < numClasses; i++)
        {

            Class cls = classes[i];
//            NSLog(@"class name:%@",NSStringFromClass(cls));
            //通过类名检索我们需要找的类
            /*
            if([NSStringFromClass(cls) isEqualToString:@"MyClass"]) {
                NSLog(@"找到了MyClass");
            }*/
            // 通过协议来查找我们需要的类

            if(class_conformsToProtocol(cls, @protocol(AnimationProtocol))) {
                id<AnimationProtocol> instance = [[cls alloc] init];
                [instance test];
            }    
        }
        free(classes);
    }
    NSLog(@"numClasses:%d",numClasses);

==================华丽的分割线来了======================
    NSMutableArray* intercepterClasses = [NSMutableArray array];
    int numClasses;
    Class * classes = NULL;
    classes = NULL;
    numClasses = objc_getClassList(NULL, 0);
    if (numClasses > 0 )
    {
        Protocol* aopProtocol = @protocol(ZWIntercepterProtocol);

        classes = (Class *)malloc(sizeof(Class) * numClasses);

        numClasses = objc_getClassList(classes, numClasses);
        for (NSInteger i = 0; i < numClasses; i++)
        {
            Class cls = classes[i];

            for ( Class thisClass = cls; nil != thisClass ; thisClass = class_getSuperclass( thisClass ) )
            {
                if(class_conformsToProtocol(thisClass, aopProtocol)) {
                    [intercepterClasses addObject:cls];
                }
            }
        }
        free(classes);
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    Class myCls = NSClassFromString(@"MyClass");
    id instance = [[myCls alloc] init];
    [instance performSelector:@selector(sayHello:) withObject:@"Hi"];
    NSLog(@"%@",myCls);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值