美文网首页
基于Aspects和JSContext对热更新的小理解

基于Aspects和JSContext对热更新的小理解

作者: JiangDaDaaa | 来源:发表于2019-05-08 16:16 被阅读0次

    看了一下网上对Aspects做热修复的代码,代码是用不了的,所以有兴趣看了一下,并且做了一定的修改

    用到的知识

    • JavaScriptCore
    • Aspects
    • runtime message

    热修复

    先说说热修复,前人已经对这里描述的挺清楚了,这里引用一下

    iOS使用Aspects做简单热修复原理

    热更新

    原文里面的

        [self context][@"runClassWith2Paramters"] = ^id(NSString *className, NSString *selectorName, id obj1, id obj2) {
            return [self _runClassWithClassName:className selector:selectorName obj1:obj1 obj2:obj2];
        };
    

    这种方法传参传了id,不知道是怎么做到的,于是自己做了一定的修改,把id obj改为了json字符串,自定义了使用的方法,在传参方面增加了基础参数的添加方法,在代码结构里面添加了几个demo,欢迎食用。

    主要方法

    + (void)_runInstanceWithInstance:(NSString *)instanceName keyPath:(NSString *)keyPath selector:(NSString *)selector parameter1:(NSString *)parameter1 parameter2:(NSString *)parameter2 {
        
        
        /*
            HotFixManager 是作为存储实例的一个单例,如果跑实例方法却又重新alloc init的话,
            在当前页面上就无法展示了,具体可以查看demo
        */ 
        //搜索当前实例是否存在,如果存在的话继续
        id instance = [[HotFixManager shareManager] ViewController];
        
        if (!instance) {
            NSLog(@"对象未找到");
            return ;
        }
        if (keyPath) {
            instance = [instance valueForKeyPath:keyPath];
        }
        
        // 1.通过方法调用者创建方法签名;此方法是NSObject 的方法
        NSMethodSignature *sig = [[instance class] instanceMethodSignatureForSelector:NSSelectorFromString(selector)];
        // 2.通过方法签名 生成NSInvocation
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
        invocation.target = instance;
        invocation.selector = NSSelectorFromString(selector);
        // 注意 参数必须从2开始 因为0跟1已经被self,_cmd占用了
        // 3.对parameter进行操作
        if(parameter1) {
            id obj1 = [self fixObject:[self transferDictionary:parameter1]];
            [invocation setArgument:&obj1 atIndex:2];
        }
        
        if (parameter2) {
            id obj2 = [self fixObject:[self transferDictionary:parameter2]];
            [invocation setArgument:&obj2 atIndex:3];
        }
        //执行invoke
        [invocation invoke];
    }
    

    获取参数的方法

    @interface ParamsHandler : NSObject
    
    /** 字典处理 */
    - initWithDictionary:(NSDictionary *)dic;
    
    /** 处理JS返回回来的Json字符串,返回基本对象 */
    - (id)fixIt;
    
    @property (nonatomic, strong) NSString *type;
    @property (nonatomic, strong) NSString *cls;
    @property (nonatomic, strong) NSString *selector;
    @property (nonatomic, strong) NSArray *parameters;
    @property (nonatomic, strong) NSString *keyPath;
    
    @end
    
    - (id)fixIt {
        NSObject *obj;
        if ([self.type isEqualToString:@"instance"]) { //实例方法,将JS传过来的json字符串转化为iOS对象
            Class class = NSClassFromString(self.cls);
            // 这里就仅限传两个参数,主要是比较懒,有需要的同学自己添加两个以上的吧
            
            if (_parameters.count == 0) {
                obj = ((NSObject* (*) (id,SEL)) objc_msgSend) ([class alloc],sel_registerName(self.selector.UTF8String));
            } else if (_parameters.count == 1) {
                obj = ((NSObject* (*) (id,SEL,NSObject *)) objc_msgSend) ([class alloc],sel_registerName(self.selector.UTF8String),_parameters[0]);
            } else if (_parameters.count == 2) {
                obj = ((NSObject* (*) (id,SEL,NSObject *,NSObject *)) objc_msgSend) ([class alloc],sel_registerName(self.selector.UTF8String),_parameters[0],_parameters[1]);
            }
        } else if ([self.type isEqualToString:@"class"]) { // 类方法
            Class class = NSClassFromString(self.cls);
            if (_parameters.count == 0) {
                obj = ((NSObject* (*) (id,SEL)) objc_msgSend) (class,sel_registerName(self.selector.UTF8String));
            } else if (_parameters.count == 1) {
                obj = ((NSObject* (*) (id,SEL,NSObject *)) objc_msgSend) (class,sel_registerName(self.selector.UTF8String),_parameters[0]);
            } if (_parameters.count == 2) {
                obj = ((NSObject* (*) (id,SEL,NSObject *,NSObject *)) objc_msgSend) (class ,sel_registerName(self.selector.UTF8String),_parameters[0],_parameters[1]);
            }
        }
        
        return obj;
    }
    
    

    demo地址

    相关文章

      网友评论

          本文标题:基于Aspects和JSContext对热更新的小理解

          本文链接:https://www.haomeiwen.com/subject/ehhvoqtx.html