20

私は非常に奇妙な問題に遭遇しました。私は完全に道に迷ったので、誰かがここで私を助けてくれるかどうか疑問に思っていました.

コンテキスト: 比較的単純な階層を持つアプリを開発しています。ビューコントローラーはほんの少しですが、高解像度の画像がかなりあります。それらはUIScrollViewいくつかのテキストなどで表示されます。ポートレートモードでテストしている間、スクロールビューはまったくスムーズにスクロールしませんでした。フレームレートが 4 ~ 5 fps に落ちたようです。最初は、高解像度の画像のせいだと思いました。

しかしその後、iPad を横向きモードにすると、すべてがスムーズに実行されました。私は縦向きと横向きの別々の xib ファイルを持っているので、縦向きの xib に問題があるはずだと思いました。それはありませんでした。どちらも同じ VC クラスを持っていたため、同じコードを使用し、両方の xib は、ビューのサイズと位置を除いてほぼ同じです。

問題を絞り込むために、Instrument の TimeProfiler を使用して問題の原因を調べました。結局のところ、TimeProfiler は[NSISEngine optimize](によってトリガーされたNSLayoutConstraint) への呼び出しをいくつか示しました。縦向きモードでは、より多くの呼び出しが行われ、それらの呼び出しにかかる時間ははるかに長くなりました。ツリーをさらに下に見ると、ポートレート モードで[NSISEngine optimize]は呼び出され[NSISEngine fixupIntegralizationViolations]、ランドスケープ モードでは呼び出されないことがわかりました。

rootVCとrootVCによって提示される他の1つを除いて、アプリからすべてのviewcontrollerを削除しました。提示された vc には、いくつかの画像、ボタン、およびいくつかのアニメーションが含まれています。両方の向きに xib が 1 つだけあり、(他のすべてと同様に) autolayout でレイアウトされます。

レイアウトは両方の向きで正常に機能し、あいまいさはありません (私が知る限り、少なくとも何も表示されpo [[UIWindow keyWindow] _autolayoutTrace]ません)。

VC のプレゼンテーション プロセスの TimeProfile のスクリーンショットを添付しました。1 つはポートレート用、もう 1 つはランドスケープ用です。ご覧のとおり、横向きでは呼び出しに[NSISEngine optimize]1 ミリ秒しかかかりませんが、縦向きでは 3000 ミリ秒以上かかります。

その理由を教えてくれる人はいますか?または、問題が何であるかを知るために何ができるか考えていますか?

どんな助けでも大歓迎です!

どうも

画像の拡大版へのリンク:リンク

計測器のタイムプロファイラーのスクリーンショット

4

3 に答える 3

4

非 Retina iPad またはポートレート モードの Retina iPad で適切に機能する、適度に複雑なビューで同じ問題に遭遇しました。Retina デバイスのランドスケープ モードでは、ポップオーバーを表示するか、ビュー スタックに別のビューをプッシュするのに 10 倍の時間がかかりました。ビューコントローラーでXIBファイルをハンドコーディングされたloadViewに置き換えることになりました。これで問題が解消されたようです。Interface builder は過度の制約を作成する傾向があるため、それを制御することが、優れた自動レイアウト パフォーマンスの鍵となります。

この問題に関するサポート チケットもオープンしました。

アップデート:

私は自分の状況で原因を見つけました。それは次の一連の制約でした。

NSArray *constraints = [NSLayoutConstraint
                        constraintsWithVisualFormat : @"|[sunLabel][monLabel(==sunLabel)][tueLabel(==sunLabel)][wedLabel(==sunLabel)][thuLabel(==sunLabel)][friLabel(==sunLabel)][satLabel(==sunLabel)]|"
                        options : 0
                        metrics : nil
                        views : labelViewsDictionary];

親ビュー内の 7 つのラベルがすべて同じサイズを共有し、すべてが親ビューの幅を拡張することを指定します。特に親ビューの幅が 7 で割り切れないため、レイアウトの過度のリレーショナルな性質が自動レイアウト フィットを与えていたと思います。

それを解決するために、各ラベルの幅を指定する一連の制約を作成し、それらの制約を適用しました。デバイスが回転すると親の幅が変わるので、戻って制約の定数を親ビューの幅の 1/7 になるように調整します。これはうまく機能し、ポップオーバーの読み込みプロセスは 2000 ミリ秒ではなく 300 ミリ秒未満になりました。

于 2013-03-29T13:30:04.160 に答える
3

この問題に関して技術サポートにリクエストを提出したところ、最終的にはバグである可能性が高いという回答が得られました。バグレポートが提出されます。うまくいけば、彼らはすぐにそれを修正します。ニュースがあれば、この回答を更新します。

于 2012-10-26T22:03:59.600 に答える
0

昨日、iPad iOS6.1デバイスで同じ問題が発生しました。アプリをインストルメント化すると、メソッド fixupIntegralizationViolations が呼び出されるたびに約 300 ミリ秒かかり (約 20 回、これはかなりの量)、アプリがまったく役に立たないことがわかりました。

私の問題は、Jack Cox のコメントと非常によく似ていましたが、別の方法で解決しました。私の制約は次のとおりです。

@"H:|[allButton][inStoreButton(==allButton)][onlineButton(==allButton)][sortButton(50)]|"

問題は、ここでのparentViewがiPadの横幅全体であるため、この制約の計算により、各ボタンにこの幅が与えられていたことです: (1024-50)/3 = 324.6666667.

これは通常、autolayout では大きな浮動小数点数を処理して正しく丸めるため問題にはなりませんが、iPad iOS6 ランドスケープでは、この数値を丸めると UI をブロックするバグが発生するようです。これを回避するには、sortButton を 52 に変更するだけで済み、各ボタンの幅は (1024-52)/3 = 324 になりました。現在、メソッド fixupIntegralizationViolations は、呼び出されるたびに約 1 ミリ秒かかります。

興味深いことに、52 を使用すると横向きでは 10 進数ではありませんが、縦向きでは 10 進数になります: (768-52)/3 = 238.666667. ただし、ポートレートにはバグがないようで、自動レイアウトは数値を正しく丸めます。

于 2014-05-15T15:02:21.003 に答える