开发中往往会遇到应用上线但是还是存在bug的情况,这个时候我们需要及时更新错误的方法,来进行热修复,然后在苹果将热更新禁掉后,大多时候都需要重新审核来发布新的版本更新,然后JSPatch,可以通过腾讯Bugly平台来进行线上修复方法的骚操作。对于我这种竟然出现小bug的人来说就是神器。

先上资源链接。

【链接】腾讯Bugly-一种愉悦的开发方式_平台内有应用升级的功能支持,里面有对应的JSpatch的SDK,使用很简单。

http://bugly.qq.com

JSPatch-基础用法,里面有相关OC语法的转换,但是不是很全,遇到了很多坑。

https://github.com/bang590/JSPatch/wiki/JSPatch

OC转换JS语法转换器。

http://www.jspatch.com/Tools/convertor

接下来我会详细说明一下我在使用时遇到的问题。

之前项目中因为请求下来的数据没有做分类,导致了一些不需要的数据展示,然而项目已经上线,只能通过热修复去修复对应的方法。

下面的代码是我修改之后的正确OC方法。

- (NSInteger)sheetView:(SheetView *)sheetView numberOfRowsInSection:(NSInteger)section
{NSMutableArray *data = [[NSMutableArray alloc] initWithCapacity:0];if ([self.logFuncName isEqualToString:@"基站故障衍生告警查询结果"]) {for (int i = 0; i<dataSource.count; i++) {NSDictionary *dic = [datas objectAtIndex:i];NSDictionary *dic2 = [dataSource objectAtIndex:i];NSString *is_derive = [dic objectForKey:@"Is_derive"];if ([is_derive isEqualToString:@"0"]) {} else {[data addObject:dic2];}}if (dataSource.count == datas.count) {dataSource = [data mutableCopy];}if (screeningDatas.count != 0) {return screeningDatas.count;} else {return dataSource.count;}} else {if (screeningDatas.count != 0) {return screeningDatas.count;} else {return dataSource.count;}}
}  

上面的方法很麻烦,但是是应急的一种方法,因为在转换变成语言的时候,是按照方法横数来的,我只能从这个小方法里面改最容易。 这个方法在OC语言中是完全没问题的。然后我通过JS语法转换之后生成了下面的代码。

require("NSMutableArray");defineClass("(方法所在控制器的类名)", {sheetView_numberOfRowsInSection: function(sheetView, section) {var data = NSMutableArray.alloc().initWithCapacity(0);if (self.logFuncName().isEqualToString("基站故障衍生告警查询结果")) {for (var i = 0; i < dataSource.count(); i++) {var dic = datas.objectAtIndex(i);var dic2 = dataSource.objectAtIndex(i);var is_derive = dic.objectForKey("Is_derive");if (is_derive.isEqualToString("0")) {} else {data.addObject(dic2);}}if (dataSource.count() == datas.count()) {dataSource = data.mutableCopy();}if (screeningDatas.count() != 0) {return screeningDatas.count();} else {return dataSource.count();}} else {if (screeningDatas.count() != 0) {return screeningDatas.count();} else {return dataSource.count();}}}
}, {});

转换之后,转换器没有给我提示报错,但是在部署代码时,怎么都无法运行,后来找到了原因,这里我要强调一下,因为JS语法中的字典和数组是没有[]方法的所以不能使用array[i]的方法,而要使用[datas objectAtIndex:i],同理字典也是没有[]方法的。

上面代码存在了两个问题。

1.私有变量没有处理。这个方法中的,dataSource,datas,screeningDatas,都是所在类的私有属性。在这里是需要做特殊处理的,要先定义一个指针去获取私有变量的地址,才能在方法中使用。

2.self.logFuncName(),logFuncName是当前控制器父类的私有变量,也就是我的基类里面的变量,如果要使用,需要在第一行代码中require("NSMutableArray");加入对应类的名字-->require("NSMutableArray, (类名)");

修改之后的JS代码如下:

require("NSMutableArray");defineClass("GDSearchResultsVC", {sheetView_numberOfRowsInSection: function(sheetView, section) {var data = NSMutableArray.alloc().initWithCapacity(0);var dataSource = self.valueForKey("dataSource");var datas = self.valueForKey("datas");var screeningDatas = self.valueForKey("screeningDatas");var columns = self.valueForKey("columns");if (columns.count() == 4) {for (var i = 0; i < dataSource.count(); i++) {var dic = datas.objectAtIndex(i);var dic2 = dataSource.objectAtIndex(i);var is_derive = dic.objectForKey("Is_derive");if (is_derive.isEqualToString("0")) {} else {data.addObject(dic2);}}if (dataSource.count() == datas.count()) {dataSource = data.mutableCopy();}self.setValue_forKey(screeningDatas, "screeningDatas");self.setValue_forKey(dataSource, "dataSource");if (screeningDatas.count() != 0) {return screeningDatas.count();} else {return dataSource.count();}} else {if (screeningDatas.count() != 0) {return screeningDatas.count();} else {return dataSource.count();}}}
}, {});

OC转JS语法中还有其他的比较容易遇到的坑:

1.JS数组、字典、字符串等等和OC的都不一样
2.JS不能识别枚举

_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:0];

UIPageViewControllerTransitionStylePageCurl和UIPageViewControllerNavigationOrientationHorizontal全部都不能识别,所以都直接改成对应的枚举值。

3.CGRect也是一个坑,最多的是在设置frame的时候,比如:
view.frame.origin.x
在js应该写成:view.frame().x (特别注意不是view.frame().origin().x)
CGRectMake(20, 20, 100, 100)
应该写成:{x:20, y:20, width:100, height:100}

4.GCD写法转换

    //OCdispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{_timer = [NSTimer scheduledTimerWithTimeInterval:TimeInterval target:self selector:@selector(repeat) userInfo:nil repeats:YES];[_timer fire];});

这里在转换成JS语法时,要注意两点,在JS语法中dispatch_after(dispatch_time())已经做了处理,所以直接使用JS语法的dispatch_after即可,然后30.f这里要注意,JS语法时没有.f的方法的。 所以要写成30.0。然后TimeInterval这里时全局变量,可以直接换成对应的值。_timer时私有变量要使用self.valueForKey和self.setValue_forKey去处理。

    //JSvar timer = self.valueForKey("_timer");dispatch_after(30.0, function(){timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats(300, self, "repeat", null, YES);timer.fire();self.setValue_forKey(timer, "_timer");});

5.JS数组与OC数组字典等处理

        var keys = [ "failureoccurtime", "appendtime", "clearAlarmTime", "appendtype", "netcellname", "businessstate", "subalarminfo", "alarmobj", "alarmname" ];var titles = [ "故障发生时间", "追加时间", "告警消除时间", "追加类型", "网元名称", "业务状态", "子告警信息", "子告警对象", "告警名称" ];var arr = NSMutableArray.new();var dic = subAlarm.objectAtIndex(indexPath.row());for (var i = 0; i < 9; i++) {var key = keys[i];var info = dic[key];if (info == null || info.isKindOfClass(NSNull.class())) {info = "";}arr.addObject(NSString.stringWithFormat("%@:%@", titles[i], info));}

keys和titles,dic等都是JS数组字典,不能使用OC的objec的方法,可以直接使用[]方法调用。

6.if判断的坑

当判断字符串的时候要使用info == false    而不能用 info == null 不好使。

7.C函数的转换

第一个参数是函数名,第二个参数是返回值类型和参数类型,用字符串表示,第一个类型为返回值,后续为参数类型。例如这样一个C函数:

int funcA(void *ptr, NSObject *obj, float num) {}

需要这样定义:

defineCFunction("funcA", "int, void *, NSObject *, float")

目前支持的参数类型有:idBOOLintvoidcharshortunsigned shortunsigned intlongunsigned longlong longunsigned long longfloatdoubleboolsize_tCGFloatNSIntegerClassvoid*

调试:

在进行JSPatch是否生效调试过程中,我是通过苹果自带的Safari去调试的。

首先打开Safari浏览器: Safari浏览器 -> 偏好设置 -> 高级最下面,显示开发选项进行勾选。

然后运行模拟器,如果需要真机调试,请在手机上打开对应设置,在设置中找到Safari 浏览器 -> 高级 -> Web 检查器 ->打开开关。

然后运行对应的版本号,build对应的程序。

点开JSContext就可以看到对应的下载文件了,里面JSPatch.js是SDK,main.js是我们部署的补丁文件。运行到对应的控制器的方法的时候,应用就会直接走main.js的替换方法了,OC中的原方法将不会进行。

一篇关于JSPatch, 线上直接改BUG的利器,OC语法转换时遇到的坑相关推荐

  1. MySQL排查篇:该如何定位并解决线上突发的Bug与疑难杂症?

    前面两章中,聊到了关于数据库性能优化的话题,而本文则再来聊一聊关于MySQL线上排查方面的话题.线上排查.性能优化等内容是面试过程中的"常客",而对于线上遇到的"疑难杂症 ...

  2. 测试人员做到这几点,线上80%的BUG将落入你手,企业将避免重大风险

    BUG事故给敲了很大的警钟,也给公司带来重大损失,作为测试人员,我们如何提现发现线上BUG并及时解决,避免落入用户手中,给企业带来无法挽回的损失. 案例1: 1月20日凌晨,拼多多App因技术漏洞,用 ...

  3. 线上一次fullgc搞得鸡飞狗跳后,我总结了这篇文章

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  4. 线上服务的FGC问题排查,看这篇就够了!

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  5. 【转】线上服务的FGC问题排查,看这篇就够了!

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  6. 科普篇|法治宣传线上答题活动小程序界面功能全介绍

    科普篇|法治宣传线上答题活动小程序界面功能全介绍 为深入学习贯彻二十大精神,努力使尊法学法守法用法在全社会蔚然成风,切实推动全民法治宣传教育深入开展,xx举办全民法治宣传线上答题活动. 第一.主界面展 ...

  7. 线上日志集中化可视化管理:ELK

    本文来自网易云社区 作者:王贝 为什么推荐ELK: 当线上服务器出了问题,我们要做的最重要的事情是什么?当需要实时监控跟踪服务器的健康情况,我们又要拿什么去分析?大家一定会说,去看日志,去分析日志.是 ...

  8. ICLR 2022入选论文线上分享预告:一作解读,不容错过

    01 ICLR介绍 ICLR,全称为International Conference on Learning Representations(国际学习表征会议),自2013年成立至今仅九年的时间,它已 ...

  9. curl命令java_让 Bug 无处藏身,Java 线上问题排查思路、常用工具

    本文总结了一些常见的线上应急现象和对应排查步骤和工具.分享的主要目的是想让对线上问题接触少的同学有个预先认知,免得在遇到实际问题时手忙脚乱. 只不过这里先提示一下.在线上应急过程中要记住,只有一个总体 ...

最新文章

  1. spring-java.lang.stackOverFlowError
  2. groovy --不注意的小错误(java.lang.String.positive() is applicable)
  3. Hadoop技术之Hadoop HA 机制学习
  4. 程序员外包避坑指南?
  5. [转]经典的C语言著作,“C语言四书五经”
  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 排版:设定文本对齐,段落中超出屏幕部分文字自动换行...
  7. linux服务器运维操作命令,Windows和Linux系统服务器运维基本操作指令
  8. 常见php面试题,常见的 PHP 面试题和答案分享
  9. 【docker】第三节:nginx通过外部无法访问的情况解决方法。
  10. Nacos Spring Boot 快速开始
  11. 怎么将短连接修改为长连接_回音壁怎么选?Redmi这个还不错
  12. CSS笔记 - fgm练习 2-10 - 提示框效果 (清除子元素浮动高度塌陷的影响)
  13. 英国莽汉司机认罪:放任特斯拉自动驾驶,自己躺在副驾悠哉悠哉
  14. 关于循环经济的三维展示
  15. 学习动态性能表3----v$session_wait
  16. Exchange 2010 证书续期
  17. 知识产权(笔记 1-3章)
  18. [20160831]关于数据块Checksum.txt
  19. 以太坊生态缺陷导致的一起亿级代币盗窃大案
  20. java打印 好看的图形_分享java打印简单图形的实现代码

热门文章

  1. Kafka之auto.offset.reset值解析
  2. 卸载一个软件,干干净净
  3. 【无标题】2022年10月22日 20点 程序爱生活 纳指和恒指反弹的概率还在,但是反弹做空为主。敏感因子第一次出现折价缩小,或许春天不太远,还需要观察!
  4. 计算机辅助翻译相关文献,计算机辅助翻译的知识结构与研究热点——基于CiteSpace的计量分析...
  5. 学完oracle的总结
  6. 初学者学习maya软件,年薪逐步上升,他是怎么做到的?
  7. tp5.1 多域名多模块设置
  8. 技术合伙人必备攻略---app开发技术栈调研--多种方案对比--uniapp学习路线
  9. GBase 8c V3.0.0数据类型——HLL函数和操作符(操作符)
  10. 【详解】C语言实现双色球(含冒泡排序法)