cocos2d-x

AutoReleasePoolとCrashOfApplication

More than 3 years have passed since last update.

特に 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 );
    }
}