0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AutoReleasePoolとCrashOfApplication

Last updated at Posted at 2015-02-07

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?