1、對象爲空帶來的問題
對象使用前要判斷空,網頁遇到空對象的執行,可能可以忽略錯誤繼續執行下去,但編譯成 Android 後,空必奔,所以前期開發要養成判空的好習慣,不夠後面改起來就呵呵了。
2、代碼執行快於渲染帶來的問題
在 onLoad、onEnable 和 start 方法裏用代碼方式生成節點時,如果該節點要使用其他節點的參數輔助生成時可能會出問題,因爲這兩個方法執行時,節點並沒有渲染出來,一些基於屏幕的屬性沒有最終確定(比如基於世界節點的 position),這時候代碼生成的節點基於這些屬性去設置,就會出現問題,解決的方法是延遲一幀去做操作。這種情況也適用於,如果要對用代碼添加的節點做類似於 position 這樣的動畫時,也會報找不到 _axxxx 的錯誤。
this.scheduleOnce(() => { // 回調 } )
調度一個只運行一次的回調函數,可以指定 0 讓回調函數在下一幀立即執行或者在一定的延時之後執行:
/**
!#en Schedules a callback function that runs only once, with a delay of 0 or larger.
!#zh 調度一個只運行一次的回調函數,可以指定 0 讓回調函數在下一幀立即執行或者在一定的延時之後執行。
@param callback A function wrapped as a selector
@param delay The amount of time that the first tick will wait before execution. Unit: s
*/
scheduleOnce(callback: Function, delay?: number): void;
然後要記住一點,如果一個行爲是異步的,那麼,這個方法要作用於異步回調之後,操作相應屬性時,千萬不能貪方便,直接加在行爲上。之前就遇到過加在一個異步行爲上,然後調起其他 app 頁面,然後異步在沒有回來之前回調了,這時還沒有渲染,位置屬性是沒有的,回到 Cocos 頁纔開始渲染,然後位置不是預想的結果,最後搞了好久才發現這個問題。
scheduleOnce 算是神器來着,如果在跳到其它 app 後回來時要做某些事情,然後跳回來沒有回調,這種情況,可以在離開本 app 前,scheduleOnce 一個任務,需要的話可以加一下延遲,然後,跳轉後只要重新打開本 app,都會調用 scheduleOnce 指定的任務。
3、判斷一個字符串是否包含特定字符串
// 該方式在某些手機系統會報錯
xxxString.includes('xxx')
// 採用該方式替代上面的方式
xxxString.indexOf('xxx') >= 0
4、異步加載資源造成的父節點掛載錯誤問題
加載一個預製資源,在加載還沒有完成時,就跳到了其他 Scene,這時預製資源加載完成回調,在預製資源中設置 parent 時,如果採用如下方式設置,那麼,這時的 parent 就不是原先預想的,而是剛打開的 Scene:
this.node.parent = cc.director.getScene();
parent 不是預想的,那麼,如果在預製資源中通過下面的方式去獲取目標節點,就會報錯:
let targetNode = cc.find('Canvas/nodeParent/targetNode');
let nodeParent = targetNode.parent;
5、getComponent: Type must be non-nil
項目編譯部署後,在相應 Scene 中,界面只有初始化的 UI,各種數據加載和交互都無效,不管點擊哪個節點(該節點有點擊的交互邏輯)都會報這個錯誤,也不指明報錯位置,找了很久都沒找出來,而且在 CocosCreater 中通過瀏覽器 debug 不會報錯。只能形而上一回,把之前寫的代碼重新寫一遍,還是一直解決不了,最後只能從 getComponent 入手,新寫的代碼中只用到一處 getComponent :
onClickBtn() {
this.share(() => {
this.tipNode.getComponent('haha').share(
() => {
this.close();
}
);
});
},
share(callBack) {
... ...
utils.bind(() => {
utils.userInfo(() => {
callBack && callBack();
})
}, () => {
this.close();
});
... ...
},
節點一定是掛載了,那就猜測是 this 作用域問題,畢竟這貨經常惹事,一改,呵呵,果然是:
onClickBtn() {
let that = this;
this.share(() => {
that.tipNode.getComponent('haha').share(
() => {
that.close();
}
);
});
},
以後遇到要把回調函數傳入另一個 js 的情況,一定要用 let that = this; 代替 this 的直接引用 !!!
然後,又遇到會有這個問題的另一種情況:如果一個 node 掛載了 Button,並且 Click Event 改成大於0,但是沒有方法掛載上去,點擊的時候也會報這個錯誤。