白黒羊

白黒羊

白黒羊

  • Home
  • Products
  • News
  • Support
  • Contact

SHIROKUROHITSUJI

UnityのiOSビルドのフリーズを解消した話

2020年10月5日C#, iOS, Unity By: shimahinuko

何個か修正を追加してUnityEditor自体やいくつかのアセットをバージョンアップしてiOSビルドしたところ途中でフリーズして動かなくなる事態に見舞われました。

問題箇所

適当なintの値が与えられているFooEnumというEnumの3桁目までの値の大小を比較してくれるComparerをOrderByで使おうとしたらダメでした。

public void main() {
    _map = new Dictionary<FooEnum, Bar>();
    
    // _mapに値を代入
    
    foreach(var tuple in 
        _map
            .OrderBy(pair => pair.Key,
                Comparer<FooEnum>.Create(
                    (left, right) =>
                    {            
                        var lv = (int) left;
                        var rv = (int) right;
                        return rv % 1000 - lv % 1000;
                    })) )
    // foreachで行う処理
}

修正版

別にIComparerを継承したクラスを作ってやると解決しました。

public void main() {
    _map = new Dictionary<FooEnum, Bar>();    
    // _mapに値を代入

    var comparer = new FooEnumComparer();
    var sorted = new SortedDictionary<FooEnum, Bar>(
         _map
         .ToDictionary(pair => pair.Key,
             pair => pair.Value), comparer);
    
    foreach(var tuple in sorted)  // foreachで行う処理
}

public class FooEnumComparer : IComparer<FooEnum>
{
    public int Compare(FooEnum left, FooEnum right)
    {
        var lv = (int) left;
        var rv = (int) right;
        return (rv % 1000 - lv % 1000) * 1000 + (rv - lv);
    }
}

原因

LINQとか、Enumとかをil2cppと組み合わせると死ぬときもあるみたいな話だと思うのですが、具体的にこれがダメだからということはわからず……。

公式マニュアルの「クロージャと匿名メソッド」の項に、

C#内のメソッド参照は全て参照型であり、したがってヒープに割り当てられるということです。
匿名メソッドをクロージャに変換すると、クロージャを受領するメソッドへ渡すために必要とされるメモリ量が大幅に増加します。

https://docs.unity3d.com/ja/current/Manual/BestPracticeUnderstandingPerformanceInUnity4-1.html

とあります(一部省略)。
この辺……?

特定に至るまで

特にエラーメッセージをはいてくれることもなく、UnityEditor上では元気に動いているのでしばらく原因がわかりませんでした。
粒度細かくビルドしていくのが大事ですよね。アジャイルアジャイル。
実機ではフリーズしてしまうだけで情報が得られなかったので、UnityCloudBuildではなく手元でXcodeを使ってビルドして、そこに出てくるログを読んだり、一時停止をすることで各スレッドがどこまで進んでいるのかを見てみました。
すでにC++のコードに変換されているものを読まないといけないのでよくわからなかったのですが、止まっている部分を見ると、ComparisonComparer<T> : IComparer<T>のような文字列が表示されていたので、自分の前回のビルドからの変更箇所と照らし合わせて特定しました。
結構時間かかったな……。

Share:

Previous

Unity Cloud Build ▶︎ Discord ▶︎ TestFlight 自動化

Next

Discord APIを使っているときに2,000文字制限に引っかかってしまったら

Leave a Comment コメントをキャンセル

カテゴリー

  • CFD (9)
    • OpenFOAM (9)
  • Design (6)
    • Adobe_XD (2)
    • Font (3)
    • Photoshop (2)
  • Diary (4)
  • Event (9)
    • AdventCalendar (3)
    • unity1week (6)
  • Git (3)
    • GitLab (2)
  • Programming (6)
    • C# (2)
      • Rider (1)
    • C++ (2)
    • javascript (2)
  • Unity (22)
    • Editor拡張 (1)
    • TextMeshPro (2)
    • UniTask (2)
    • UnityAsset (8)
    • UnityCloudBuild (2)
    • WebGL (2)
  • ゲーム (2)
    • 冠を持つ神の手 (2)
  • 機械学習 (1)
  • 開発 (19)
    • Admob (3)
    • Android (2)
    • Database (1)
      • MySQL (1)
    • DiscordAPI (2)
    • iOS (2)
    • PlayFab (1)
    • Web (2)
      • AmazonS3 (2)
      • Heroku (1)
      • RestAPI (1)
      • WordPress (1)
    • 虹の降る海 (6)
    • 設計 (1)
2020年10月
日 月 火 水 木 金 土
 123
45678910
11121314151617
18192021222324
25262728293031
« 9月   11月 »

アーカイブ

  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年5月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年2月
  • 2018年11月
  • 2018年9月
  • 2018年8月
  • 2018年7月

カテゴリー

  • Admob
  • Adobe_XD
  • AdventCalendar
  • AmazonS3
  • Android
  • C#
  • C++
  • CFD
  • Database
  • Design
  • Diary
  • DiscordAPI
  • Editor拡張
  • Event
  • Font
  • Git
  • GitLab
  • Heroku
  • iOS
  • javascript
  • MySQL
  • OpenFOAM
  • Photoshop
  • PlayFab
  • RestAPI
  • Rider
  • TextMeshPro
  • UniTask
  • Unity
  • unity1week
  • UnityAsset
  • UnityCloudBuild
  • Web
  • WebGL
  • WordPress
  • 冠を持つ神の手
  • 機械学習
  • 虹の降る海
  • 設計
  • 開発

メタ情報

  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org