CocosBuilderにリジェクトの罠!このバグ致命的!

A0003 001808

いま、Appleに申請依頼中のアプリが難産です。

3回のRejectを喰らい、4回目の申請中。今度は大丈夫かな。

いままでiPhoneのアプリを作り続けてきましたが、リジェクトらしいリジェクトは初めてかも。

リジェクトの理由は2つ。

ひとつはアプリの名称が商標の問題で却下。ドイツで商標登録されている名称なのでダメと。 似た名称のアプリは見かけるんだけど、判断の境界線が分からない。名称を変えるのが嫌だったのでドイツのAppStoreを公開対象から外してみたけど、再度リジェクト。結局あきらめてアプリの名称を変更しました。これは3回目の申請でクリア。

もうひとつの理由がクラッシュ! iPad(3Gen)でクラッシュしたからリジェクトだって。筆者もiPad(3Gen)を持っているのでテストしてるんだけどクラッシュしたことは無く、他、iPhone 3GS/4S/5でも結構テストしてるけどクラッシュしたことは無い。 メモリリークとかしてるかもしれないからテストしてよ的なAppleからのコメントもあったけど、全然リークしてないし、全く再現できず、ちょっと怪しいところを直してみて再申請してもやっぱりリジェクト!

クラッシュしてリジェクトされたときはクラッシュレポート(Crash Report)を送ってくれるんですが、レポートを見ても最初は使い方がよく分からず苦戦。 クラッシュレポートの使い方が分かったのでついでにメモしておきます。また使うことがあるかもしれないし。 クラッシュレポートはクラッシュ時のスタックトレースみたいなものですが、もらったファイルだけだとどこでクラッシュしたのかザックリしか分からず使い物になりません。 もらったtemp..XXXXXXX.crashみたいな名前のレポートファイルの他に、申請用にビルドした時に作成されているAppName.appAppName.app.dSYMファイルを使うと詳細な情報を確認できます。この3つが揃っていないと詳細を確認できないのでこのファイルは申請が通るまでは取っておいた方がいいですね。これらのファイルは、

/Users/UserName/Library/Developer/Xcode/DerivedData/AppName-XXXXXXXXXXX/Build/Products/Release-iphoneos

にあります。

3つのファイルが揃ってれば、以下のコマンドで詳細情報を調べることができます。

>export DEVELOPER_DIR=”/Applications/Xcode.app/Contents/Developer/” >/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash temp..XXXXXXX.crash AppName.app.dSYM/

これを最初知らず、闇雲に再現テストを試みてました。

さて本題。 実は最初クラッシュレポートの内容からもハッキリしたことは、分からなかったのですがCocosBuilderのモジュールの中でエラーになってるっぽい。 でも、筆者の環境ではやっぱりクラッシュしない。

クラッシュレポートには

Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Codes: EXC_ARM_DA_ALIGN at 0x201a70d6

中略

0 QuickReversal 0x000bcbcc -[CCBReader readFloat] (CCBReader.m:202)

以下略とでてます。EXC_BAD_ACCESSは開発中によく見ますが、EXC_ARM_DA_ALIGNがポイントだった。

筆者は開発中、実機でもシミュレーターでもDebugビルドでテストしてたんですが、どうやらReleseビルドでだけクラッシュするケースがあるらしい。

今後アプリを作るときはReleseビルドでもテストしておかなければダメですねぇ。Releseで実行してみたら見事にクラッシュできました。

ただ問題は筆者が作った部分ではなく、CocosBuilderCCBReader.mというモジュールのreadFloatメソッドの中。

以下のように直せば解決します。

            // using a memcpy since the compiler isn’t

            // doing the float ptr math correctly on device.

            float * pF = (float*)(bytes+currentByte);

            float f = 0;

            //original

            //memcpy(&f, pF, sizeof(float));

            //comgate write

            unsigned char* src = (unsigned char*) pF;

            unsigned char* dst = (unsigned char*) &f;

            for (int i = 0; i < 4; i++)

            {

                dst[i] = src[i];

            }

これって致命的ですね。
CocosBuilderのおかげで、Cocos2dでの画面デザインはかなり楽になったけど大きな罠がありました。

意外とハマっている人いるんじゃないでしょうか。

 

Tags: , , , , , ,