iOSをレビューする前に、プロジェクトのロード方法に注意してください

今回の主な話題：iOS監査の悲劇（拒否）を回避する方法、メモリリークの調査、ilcpp.soライブラリファイルのサイズ、il2cppコードサイズを縮小する、Strip byte Code。

---
###アセット管理
Q1: 私たちのプロジェクトはAssetBundleパッケージング方式を使用し、WWWでローカルロードを行い、プログレスバーもあり、ロードされているデータと全体的なデータを指摘するヒント枠もあります。iOSレビューに送信した後、拒否されました。ヒントは4.2.3でした。

``Guideline 4.2.3 – Design – Minimum Functionality``

``Your app did not include sufficient content in the binary for the app to function at launch, and we were required to download or unpack additional resources before we could use it.``

``We were required to download or unpack additional resources to continue using your app; however, the size of the download was not disclosed, and we were not prompted to choose to download additional resources. If your app requires additional resources, you must disclose the size of the download and prompt users before doing so.``

内部で何もダウンロードされていないことが確認されていますが、ローカルリソースのみがロードしていて、ヒントも与えました。なぜ拒否されたのか分かりません。
>いくつかの考えすべき事項があります。

>１）圧縮リソースを使用しないでください。パッケージ内のリソースには非圧縮またはLZ4圧縮形式を使用してください。パッケージ本体のサイズが敏感な場合はLZ4を使用してください。LZ4を使用する場合、アセットをロードするときに解凍必要があることに注意ください。これはAssetのローディングに時間がもっとかかることを引き起こします。フレームレートが敏感なときにアセットをロードする場合は、LoadAssetAsyncの使用を考慮する必要があります。

>２）iOSでは、WWWの代わりにLoadFromFileを使用してください。WWWはより多くのメモリを必要とします。特にwww.bytesを使用する場合、下図のように、それが役に立たなくても、LoadFromFileの2倍になります。（WWWを使用するとダウンロードする必要があることが検出された場合があるとある報告されました、まだ確認していません。）
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/850643dc-8406-df78-3182-c152b048f2de.jpeg)
>３）当社はもともと7zを使用してリソースを圧縮していましたが、却下された後、圧縮なしに変更され、スムーズにレビューに合格しました。

---
###メモリ
Q2：妙な問題に遭いました。ダンジョンを繰り返し出入りすると、合計メモリは増加し続けます（1回あたり約10MB）。この時点では、各リソースメモリ、Monoメモリ、およびLuaメモリは基本的に変更されていません。つまり、Unityによってカウントされたあるメモリはありますが、詳細情報には含まれていません。 この部分は何でしょうか？
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/49694314-292a-374f-3ec1-eb8cc080a2bf.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/9fcd24cf-0ac5-112f-41cf-24ee05218b42.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/e550cd97-d153-0036-74fd-272edadc9edd.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/ff8d7b01-d10d-7ef5-7c2a-d3182c65f1c9.png)
>問題主が提供するスクリーンショットから判断すると、AssetBundleの常駐が原因である可能性があります。毎回シーンを出入りすると、アセットのローディングはAssetBundleで行いますか？AssetBundleの数は変更されましたか？そして、3回目、4回目以降、メモリも毎回10MBずつ増加しますか？AssetBundleを使用してロードする場合、実際にはAssetBundleでロードされた一部のメモリは、Detailedモデルで観察されません。この方面から調べることをお勧めします。

---
###IL2CPP
Q3: IL2CPPの体積を減らすことについて質問します。公式ドキュメントによって、https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html
私の理解は次のとおりです。
![6-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/c36d706c-40b4-c833-40d9-03d9e83a3629.png)
しかし、実際にテストしたところ、正しくではないようです。
2018.2.7f1、左側の図にStrip Engine Codeは開きましたが、右側のほうに開きませんでした。
![7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/00df7b47-cd21-625c-7d9d-6cbf53a0a9c8.png)
いくつかの問題があります。

１）Strip Engine Codeを開いた後、いくつかのxx_Module cppファイルが欠落していることがわかりますが、これらのcppはC#とDllから転換してくるすべきですが、Byte Code StripのステップでStripする必要があります。Strip Engine Codeパラメーターの影響を受けないはずです。（公式ドキュメントがこのパラメーターはEngine Native CodeのStripのみに影響ありますと言っています。）どうする？

2）LinkステップのStripは私自身の推測です。XCodeに余り精通していませんから、Linkする時に不要なSymoblsを削除するためにどちらのCompileとLinkパラメーターは使えますが良くわかりません。この部分について何か正確な結論ありませんか？

3）Package Managerでは、不要なEngine Builtin Moudeleを明確にDisableします。例えば、AIやXRがIL2CPP の時に引き続きcppソースコードを生成します。常識に反しているように感じます。この部分は最終的にあるステップで削除されますか？

4）Strip Engine Codeは開いていますか？この前に、裁断が引き起こす問題を回避するために（特にホットアップデート）、開けないことにしましたが、現在、体積を減らすために開きたくなりました。何か注意すべき点がありませんかを聞きたいです。
>ソースコードを調べました、https://github.com/Unity-Technologies/UnityCsReference

>CodeStrippingUtils.csおよびAssemblyStripper.csにStrip Engine Codeに関するコンテンツがあります。このオプションをオンにすると、ModulesにStripを行います。（この一歩は完全には理解していません。おそらく、先にRoot Assemblyが使用するClassをフィルタして、これらのClassが使用するModuleを記録します。また、これらのModule自身のプロパティにも関連しています。）ここで、具体的に保存されたModuleとClassはファイルUnityClassRegistration.cppに記録されます。

>私の理解は以下とおります。
>Strip Engine Codeが影響するのは「Byte Code StripステップでUnity Engine CodeにStrip処理をするか」どうかということです。PackageManager内の設置をMonoの形式でパッケージしてみます。Strip Byte CodeでもStrip Assembliesでも、依然としてDisableのbuilt-in Moduleに対応するdllファイルを生成します。ここのDisableはパッケージ化のStrip操作と関係ありませんと推測します。
>上記はただUnity buildに対して私個人的な理解であります。最も重要な問題は、Strip Engine Codeを開きますかどうかということです。

>私の前回のプロジェクトでは開きました。プロジェクトにリフレクションを使用していなかったので、目前には問題ありません。以後、問題があれば直したら大丈夫です。Unityの公式ドキュメントから、「開くとコードの量を減らすことができますが、問題がある場合閉めてください。」問題主に自分のプロジェクトによって決めることをお勧めします。

---
###アセット管理
Q4: 最近、Android端末プロジェクトのパッケージかをIL2CPPの形式に変更したいですが、エクスポートされたapkのil2cpp.soファイルが40MBと大きく、libmono.soが作成した3MBのサイズよりもはるかに大きいことがわかりました。ですからapkもはるかに大きくなりました。何か解決策がありませんか？
>Libli2cpp.soにはロジックコードが含まれています。libil2cpp.soとlibmono.soのサイズを直接比較することは無意味です。一般的に、IL2CPP方式のパッケージ化がパッケージを大きくする原因はC#コードがコンパイルされてC++コードに変更すると、コードの量が急激に増えるためです。この点について、Unityの新しいバージョンも常に最適化しています。

>問題主が使用しているUnityのバージョンはなんでしょうか？Strip Engine Codeオプションが有効になっていますか？

>Unityのバージョンが新しいほど、この点についての最適化効果が高いと言われています。 公式もこれに言及しました：https://docs.unity3d.com/Manual/dotnetProfileLimitations.html

---
###アセット管理
Q5: 私のプロジェクトは、プレハブを非同期でロードするときにピークがあります。詳しく確認すると、この関数が原因であることがわかりました。これはなぜですか？どうすれば避けられますか？
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/2e4b606d-5f8e-d3d6-98b3-07dbbd7be1ad.png)
>これは、アセットを非同期ロードする時の時間コストです。アセットのローディングには常に時間コストがあります、必ずしも回避する必要はありません。アセットの非同期ローディングに頻繁ローディング問題があるかどうかを確認することを問題主にお勧めします。存在する場合には、できる限りに改善してください。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com