JSPatch是什么
借用一下官方文檔第一段
JSPatch 是一個(gè)開源項(xiàng)目苟耻,只需要在項(xiàng)目里引入極小的引擎文件曼氛,就可以使用 JavaScript 調(diào)用任何 Objective-C 的原生接口混埠,替換任意 Objective-C 原生方法踢匣。目前主要用于下發(fā) JS 腳本替換原生 Objective-C 代碼世舰,實(shí)時(shí)修復(fù)線上 bug庞瘸。 ——bang590
JSPatch使用中遇到的坑
CATCH的2.4.0中我們第一次加入了這個(gè)框架,今天正式的使用了一下许赃。JSpatch功能的強(qiáng)大不需多言,這里記錄一下使用中遇到的問題馆类。
ViewController
用JSPatch修復(fù)controller的時(shí)候一定要加上或者重寫(哪怕這兩個(gè)方法沒有修復(fù)的必要)這兩個(gè)方法混聊,否則分別會(huì)在willAppear的時(shí)候和willdisappear的時(shí)候崩給你看。
defineClass('ViewController', {
viewWillAppear: function(animated) {
self.super().viewWillAppear(animated);
//balabala...
},
viewWillDisappear: function(animated) {
self.super().viewWillDisappear(animated);
//balabala...
},
});
可變參數(shù)
本來要解決的問題很簡(jiǎn)單很蠢乾巧,有這樣一個(gè)AlertView(CATAlertView是我們封裝過的AlertView
WS(weakSelf);
CATAlertView* alert = [[CATAlertView alloc] initWithTitle:@"提示" Message:@"確定后訂單被鎖定句喜,將無法被修改。" Hidden:NO touchBlock:^(id sender, NSInteger index) {
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Order" bundle:nil];
CATPaymentViewController* viewController = [storyboard instantiateViewControllerWithIdentifier:@"CATPaymentViewController"];
viewController.order = weakSelf.order;
[weakSelf.navigationController pushViewController:viewController animated:YES];
} cancelButtonTitle:@"取消" andButtonsTitles:@"付款", nil];
[alert show];
在touchBlock中缺少了判斷
if(index == 1){
}
導(dǎo)致點(diǎn)擊取消按鈕也會(huì)觸發(fā)響應(yīng)沟于。是不是很簡(jiǎn)單很蠢咳胃,ha?
被報(bào)告了這個(gè)bug以后旷太,我打算隨手fix掉得時(shí)候展懈,突然想到正好可以試一試用js來修销睁,實(shí)踐一下,說干就干存崖,兩秒鐘寫好修復(fù)代碼
WS(weakSelf);
CATAlertView* alert = [[CATAlertView alloc] initWithTitle:@"提示" Message:@"確定后訂單被鎖定冻记,將無法被修改。" Hidden:NO touchBlock:^(id sender, NSInteger index) {
if(index == 1){
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Order" bundle:nil];
CATPaymentViewController* viewController = [storyboard instantiateViewControllerWithIdentifier:@"CATPaymentViewController"];
viewController.order = weakSelf.order;
[weakSelf.navigationController pushViewController:viewController animated:YES];
}
} cancelButtonTitle:@"取消" andButtonsTitles:@"付款", nil];
[alert show];
兩秒鐘利用作者提供的轉(zhuǎn)換器JSPatch Convertor轉(zhuǎn)換成JS代碼
require('CATAlertView,UIStoryboard');
WS(weakSelf);
var alert = CATAlertView.alloc().initWithTitle_Message_Hidden_touchBlock_cancelButtonTitle_andButtonsTitles("提示", "確定后訂單被鎖定来惧,將無法被修改冗栗。", NO, block('id,NSInteger', function(sender, index) {
var storyboard = UIStoryboard.storyboardWithName_bundle("Order", null);
var viewController = storyboard.instantiateViewControllerWithIdentifier("CATPaymentViewController");
viewController.setOrder(weakSelf.order());
weakSelf.navigationController().pushViewController_animated(viewController, YES);
}),"取消", "付款", null);
alert.show();
兩秒鐘修改一下語法錯(cuò)誤,比如這個(gè)
WS(weakSelf);
需要改成(詳見官方文檔
var weakSelf = __weak(self);
以及需要注意供搀,轉(zhuǎn)換得到的JS代碼中竟然把if(index==1)給弄沒了隅居,這里也需要補(bǔ)上......總之最后得到的JS代碼是這樣的
require('CATAlertView,UIStoryboard');
var weakSelf = __weak(self);
var alert = CATAlertView.alloc().initWithTitle_Message_Hidden_touchBlock_cancelButtonTitle_andButtonsTitles("提示", "確定后訂單被鎖定,將無法被修改葛虐。", NO, block('id,NSInteger', function(sender, index) {
if(index == 1){
var storyboard = UIStoryboard.storyboardWithName_bundle("Order", null);
var viewController = storyboard.instantiateViewControllerWithIdentifier("CATPaymentViewController");
viewController.setOrder(weakSelf.order());
weakSelf.navigationController().pushViewController_animated(viewController, YES);
}
}),"取消", "付款", null);
alert.show();
然后運(yùn)行胎源,執(zhí)行這段代碼,不出所料的崩潰了挡闰,崩潰點(diǎn)在alertview處理傳進(jìn)來的otherButtonTitle上(抱歉這個(gè)地方忘記截圖備案了乒融,THANKSGOD我們自己封裝了一下alertView才讓我們很容易定位到了崩潰點(diǎn),否則估計(jì)就是紅紅的BAD_XXXX_XXX摄悯。不斷地踩坑研究代碼赞季、查資料后終于發(fā)現(xiàn)了官方wiki中提到的這個(gè)點(diǎn)
在 JSPatch 不支持調(diào)用 [NSString stringWithFormat:@""] 方法,原因是這是參數(shù)個(gè)數(shù)可變方法奢驯,JSPatch 原理是通過 NSInvocation 動(dòng)態(tài)調(diào)用方法申钩,而 NSInvocation 不支持可變參數(shù),參見官方文檔瘪阁。
完撒遣。
.
.
.
.
.
.
.
.
.
.
……并沒有(我是有多好運(yùn)這種低級(jí)錯(cuò)誤犯了以后又撞上這樣的設(shè)定
所以,子曰曾經(jīng)過:我們?cè)谑褂靡粋€(gè)框架的時(shí)候要養(yǎng)成研究它的原理的好習(xí)慣管跺。