のキャッシュされたインスタンスを消去するときに、非常に奇妙な問題が発生しますSKTextureAtlas
。
つまり、ゲームが開始する前にSKTextureAtlas
withをプリロードtextureAtlas.preload(completionHandler:)
し、完了ハンドラーでアトラスへの参照をプライベート プロパティに保存して、後で使用できるようにメモリに保持します。
しばらくすると、このテクスチャ アトラスは不要になり、クリーンで健全な記憶を維持するために削除したいと考えています。
問題
私が抱えている問題は、(アトラスへの参照を保持していたプロパティを に設定することによって) テクスチャ アトラスを消去するとnil
、パフォーマンスが数秒間大幅に低下することです。大幅に、一定の 60 fps から 40 fps を意味します。
この時点で残されたそのアトラスへの他の参照は絶対にないことに注意してください.
興味深い: パート 1
iOS 10 でのみ発生します。iOS 9 では、はるかに古いデバイスでも完全に動作します。
興味深い: パート 2
アトラスが の形式で定義されている場合にのみ発生.spriteatlas
し.xcassets
ます。ただし、アトラスが の.atlas
外部のフォルダーである場合はそうではありません.xcassets
。
.atlas
の代わりに先に進んで使用できることはわかっていますが、そのままで app-thinning をサポートしています.spriteatlas
が、サポートしていません。.spriteatlas
.atlas
興味深い: パート 3
アトラスに少数の小さなテクスチャがある場合、パージは正常に機能します。これは、アトラスの合計サイズに関連する内部の問題がある可能性があることを示しています。しかし、なぜ?
動機
この問題の解決策/回避策を見つける背後にある動機は、バインド/描画呼び出しのバッチ処理です。同じテクスチャを使用する子ノードはすべて 1 回の描画パスでレンダリングされるため、もちろんパフォーマンスが大幅に向上します。
この問題により、基本的に複数のアトラスを作成する必要があり、その結果、複数の描画呼び出しが発生し、全体的なパフォーマンスに影響を与えます。
どんな助けでも大歓迎です。
アップデート
@Knight0fDragon によって提案されたソリューションを実装しようとしました。これは、それ自体ではなくSKTexture
s をキャッシュすることを提案していますが、残念ながら私の場合はうまくいきませんでした。SKTextureAtlas
SKTextureAtlas
元の質問で忘れていたのは、この問題はほとんどの場合発生するが、常に発生するわけではないということです。〜5回の試行ごとに完全に正常に動作します。
解決
誤って重複としてマークされた後、質問を再度開くことができなかったので、見つけた解決策をここに投稿します。
問題は、バックグラウンドで実行されているアニメーションでした。このアニメーションはこのように設定されました
let rotation = CABasicAnimation(keyPath: "transform.rotation")
rotation.fromValue = 0
rotation.toValue = 2 * M_PI
rotation.duration = 110
rotation.repeatCount = Float.infinity
のレイヤーで実行されていましたUIImageView
。このイメージ ビューは、最終的にゲーム シーンを含む別のビュー コントローラーを提示するビュー コントローラーに配置されました。
beginAppearanceTransition
これらの 2 つのビュー コントローラー間のトランジションはカスタムです。カスタム トランジション アニメーターに呼び出しを追加するのを忘れたためendAppearanceTransition
、ビュー コントローラーのライフサイクル メソッド ( viewWillAppear:
、viewWillDisappear
) は呼び出されませんでした。アニメーション。したがって、アニメーションはバックグラウンドで実行され続けました。
とはいえ、アニメーションがバックグラウンドで実行されていたとしても、キャッシュされたアトラスのクリアなど、まったく関係のないことを妨げるべきではありません。
注: 問題のあるアニメーションを含む画像ビューの画像は、問題のあるテクスチャ アトラスでは定義されていません。