zoukankan      html  css  js  c++  java
  • JSPatch

    JSPatch

    原理:在APP启动的时候,通过JavaScrptCore来执行编写的JavaScript脚本,利用OC的运行时特性来修改类的方法和属性。

    1:执行JS脚本

    #import "AppDelegate.h"
    // 导入JSPatch框架
    #import <JSPatch/JPEngine.h>
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        [Bugly startWithAppId:BuglyAppId];
        [JPEngine startEngine];
    //    加载本地的JS文件
    //    NSString *path = [[NSBundle mainBundle] pathForResource:@"firstChange" ofType:@"js"];
    //    NSString *script = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    //    [JPEngine evaluateScript:script];
    
    // 记载请求的JS文件
        [[FFNetworkHelper share] GetFile:[NSString stringWithFormat:@"xxx/%@", @"firstChange.js"] successBlock:^(id  _Nonnull responseObject) {
            [JPEngine evaluateScript:responseObject];
        } failuerBlock:^(NSString * _Nonnull str) {
    #if DEBUG
            FFShowInfo(@"JS 修复文件下载失败");
    #endif
        }];
        
        self.window = [[UIWindow alloc] initWithFrame:MainScreenBounds];                                                   
    s self.window.rootViewController = [self FF_GetTabBarController]; [self.window makeKeyAndVisible]; return YES; }

    2: 在动态修改OC类的方法和属性时的核心方法 defineClass('className', instanceMethod, classMethod)

       className--要覆盖的类名,字符串类型

       instanceMethod--实例方法

       classMethod--类方法(要修改类方法,必须有实例方法,如果实例方法省略,就会默认为instanceMethod)

    /*
    ##API
    
    defineClass(classDeclaration, instanceMethods, classMethods)
    
    @param classDeclaration: class name, super classname and protocols
    @param instanceMethods: instance methods you want to override or add
    @param classMethods: class methods you want to override or add
    
    
    
    1.Use _ to separate multiple params: 使用_链接多个参数
    
    2.Use __ to represent _ in the Objective-C method name: 如果原来的方法名中有_用__代替
    
    3.Call original method by adding prefix ORIG to the method name. 如果想调用OC中对应的初始方法,添加前缀ORIG
    
    4.Super / Property / Member variables
        a: Use self.super() to call super methods. 使用self.super()调用super method
        b: Call methods to get / set existing property. 通过get / set 方法来操作存在的属性
            // JS
            defineClass("JPTableViewController", {
                  viewDidLoad: function() {
                     var data = self.data()     //get property value
                     self.setData(data.toJS().push("JSPatch"))     //set property value
                  },
            })
        c: Use getProp() and setProp_forKey() to get / set new property 通过getProp() 和 setProp_forKey()来get / set 一个新属性
            // JS
            defineClass("JPTableViewController", {
              init: function() {
                 self = self.super().init()
                 self.setProp_forKey("JSPatch", "data")     //add new property (id data)
                 return self;
              }
              viewDidLoad: function() {
                 var data = self.getProp("data")     //get the new property value
              },
            })
        d: Use valueForKey() and setValue_forKey() to get / set member variables 成员变量操作
           // JS
            defineClass("JPTableViewController", {
              viewDidLoad: function() {
                 var data = self.valueForKey("_data")     //get member variables
                 self.setValue_forKey(["JSPatch"], "_data")     //set member variables
              },
            })
    5.You can add new methods to the existing Class, if you want to call the new method in Objective-C, all the params type is id.
      在已经存在的类中添加一个新方法,在OC中回调是,参数是id类型
    
    6.Special types
      Use hash object to represent CGRect / CGPoint / CGSize / NSRange
      // JS
        var view = UIView.alloc().initWithFrame({x:20, y:20, 100, height:100})
        view.setCenter({x: 10, y: 10})
        view.sizeThatFits({ 100, height:100})
    
        var x = view.frame.x
        var range = {location: 0, length: 1}
    
     
    
    */
    
    /// 要用到的类,用require导入
    require('UIView, NSString, NSDate, NSLog')
    /// 要重载的类, 修改viewDidLoad方法
    defineClass(
        'FFBaseViewController',
        {
            /// 实例方法
            viewDidLoad: function(){
                /// self.super() 回调 super method
                self.super().viewDidLoad();
                /// 要执行的操作
                ...
    
            };
        })
    
    /// 要重载的类, 调用viewDidLoad方法
    defineClass(
        'FFBaseViewController',
        {
            /// 实例方法
            viewDidLoad: function(){
                /// self.super() 回调 parent method
                self.ORIGviewDidLoad();
                /// 要执行的操作
                ...
    
            };
        })
    
    /// 要重载的类, 修改viewDidLoad方法, 添加一个类方法FFPrint
    defineClass(
        'FFBaseViewController',
        {
            /// 实例方法
            viewDidLoad: function(){
                /// self.super() 回调 parent method
                self.super().viewDidLoad();
                /// 要执行的操作
                ...
    
            };
        },
        {
            /// 类方法
            FFPrint: functon(){
                NSLog('类方法');
            }
        }
    )

      

  • 相关阅读:
    Error -26631: HTTP Status-Code=400 (Bad Request) for
    mysql中的制表符替换
    mysql中json数据的拼接方式
    使用Nightwatch.js做基于浏览器的web应用自动测试
    Selenium + Nightwatch 自动化测试环境搭建
    Python web 框架:web.py
    转 Python Selenium设计模式-POM
    自动化测试
    日志打印longging模块(控制台和文件同时输出)
    读取配置文件(configparser,.ini文件)
  • 原文地址:https://www.cnblogs.com/jisa/p/10792483.html
Copyright © 2011-2022 走看看