特に 2.x 系向けの話となります。
※3.x系にはDirector::getInstance()->getScheduler()->performFunctionInCocosThreadという便利なのもありますね
非UIスレッドから、cocos2d-xでお馴染みの
create系メソッドをコールするのは危険です。
CCObject::create() 等
※CREATE_FUNC等で定義されているアレ
特にAndroid版実装においては、
課金や通知、サード製のライブラリを実装する際に
JNIでC側のメソッドをコールする事があると思いますが、
JNIのメソッドは、UIスレッドとは別のスレッドから
コールされるものが多々あります。
create系のメソッドは、内部で autorelease() をしているので
AutoreleasePoolのグローバルなリストへ登録されます。
UIスレッドでは、毎フレームの最後の方に
AutoreleasePoolへ登録されているオブジェクトの整備をしているので
retainされていないオブジェクトは削除されます。
その為、例えば以下の様なコードは、アプリがクラッシュする可能性を秘めています。
static void crashTestThread(){
while(1){
auto dic = cocos2d::CCDictionary::create();
// 待てば待つほどクラッシュ確率が上がる
usleep( 1000 * 10 );
dic->release();
}
}
static void testCrash(){
auto th = std::thread( crashTestThread );
th.detach();
}
問題は、AutoreleasePoolに起因する事なので、
上記コードも以下のように書けばクラッシュを免れます。
static void crashTestThread(){
while(1){
auto dic = new cocos2d::CCDictionary();
// 待てど暮らせどクラッシュしない
usleep( 1000 * 10 );
dic->release();
}
}
static void crashTestThread(){
while(1){
cocos2d::CCDictionary dic;
// 待てど暮らせどクラッシュしない
usleep( 1000 * 10 );
}
}