最近用上了JSPatch,好用是好用,但是因為JS不熟還是踩到許多坑,浪費了不少時間。這里做個記錄,不定期更新。
Block使用
cell.selectBlock = ^(NSUInteger index){
};
上面的代碼換成JS,應該是:
var func = function(index){
};
cell.setSelectBlock(block("NSUInteger", func)); //因為是setter,所以要用set開頭
帶下劃線的變量或方法
看下面的代碼:
var hotgoods_moreurl= dataHome.hotgoods_moreurl();
單步調試到這一行代碼時報錯:method signature argument cannot be nil。加入JSPatch源碼得到更詳細的報錯信息:
- Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unrecognized selector hotgoods:moreurl for instance '。
看到了嗎,本來是訪問hotgoods_moreurl變量的,結果變成了訪問名為hotgoods:moreurl的selector。
究其原因,還是因為變量名中有下劃線,而文檔中說明原OC方法名有下劃線在的,在JS中要用雙下劃線代替。
還是沒仔細看文檔惹的禍!!!
for循環(huán)
for (var constraint in view.superview().constraints()) {}
粗看沒問題,一用大有問題,在訪問constraint的某個屬性時直接報錯并崩潰,錯誤提示:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'js exception, msg: undefined is not an object (evaluating 'this[methodName].bind')
—— JS里這樣for循環(huán)也是有問題的
歸根到底是JS中的Array與OC中的NSArray是不同的,在js中訪問NSArray中的元素還是乖乖用ObjectAtIndex方法,并使用正常的for循環(huán)方法:
var count = view.superview().constraints().count();
var index = 0;
for (index = 0; index < count; index++) {
var constraint = view.superview().constraints().objectAtIndex(index);
}
for...in
首先從 OC 返回的 NSArray / NSDictionary 對象是不能直接用 for...in 遍歷的,需要調用 .toJS()后才能進行遍歷,詳情見上文。
然后在遍歷數組時,JavaScript 的 for...in 語法定義與 Objective-C 不同:
//OC
NSArray *arr = @[@"name", @"age"];
for (var o in arr) {
NSLog(@"%@", o); //輸出 name age
}
var arr = ["name", "age"];
for (var o in arr) {
console.log(o); //輸出 0, 1,表示遍歷數組的序號
console.log(arr[o]); //輸出 name age,這樣才表示數組的值
}
比較
viewA和viewB比較在OC里可以用viewA == viewB,但是在JS里進行類似的比較卻是會出問題的,在OC里面相等而在JS里面未必相等。
正確辦法是用isEqual來進行viewA和viewB的比較。