web-dev-qa-db-ja.com

presentViewControllerのパフォーマンスが遅い-presentingコントローラーの複雑さに依存しますか?

私はビューコントローラーを提示しています:

SCAAboutController2 *controller = [[SCAAboutController2 alloc] initWithNibName:nil bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navController animated:YES completion:nil];

デバイスは、表示される前に3〜4秒間ハングします。 Instrumentsを使用してこれを診断しようとしましたが、ほとんどの時間はmainに費やされているようです-

enter image description here

これは同じプロファイルですが、システムライブラリが非表示になっています。

enter image description here

これらのメッセージはどれも私には認識できないため、パフォーマンスの問題のデバッグを開始する方法がわかりません。

メインコードがメインスレッドで実行されていることを確認する必要があることを他の場所で読みました。ただし、次の変更は何も改善していません。

dispatch_async(dispatch_get_main_queue(), ^{
        SCAAboutController2 *controller = [[SCAAboutController2 alloc] initWithNibName:nil bundle:nil];
        UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
        [self presentViewController:navController animated:YES completion:nil];
    });

進歩する方法についてのアイデアがすぐになくなってしまいました。さらに調査するにはどうすればよいですか、および/またはプレゼンテーションが遅い根本的な原因は何でしょうか?

編集

いくつかの紛らわしい発見:

  • 表示されたViewControllerからすべてのコードを削除しました。パフォーマンスは影響を受けません。
  • 同じ場所から別のボタンを介して提示する別のコントローラーがあります。同様に遅いです。
  • presenting ingコントローラーには非常に多くのサブビューと制約があります-一部の子ビューコントローラーですら。これらを設定するコードを削除すると、問題が解決します。
  • 提示するコントローラーのviewWillDisappearには何も追加されません。

編集2

問題は、メイン(提示)コントローラーに追加する一連のレイアウト制約に集中していることを発見しました。具体的には、いくつかの子コントローラー(タイプteamController)をループして、制約を追加します。

[self.browser addConstraint:[NSLayoutConstraint constraintWithItem:teamController.view
                                                         attribute:NSLayoutAttributeWidth
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:self.browser
                                                         attribute:NSLayoutAttributeWidth
                                                        multiplier:1
                                                          constant:0]];

子コントローラーは10個だけです。また奇妙なことに、代わりに以下を使用しても、そのような問題はありません。

[self.browser.contentView addConstraint:[NSLayoutConstraint constraintWithItem:teamController.view
                                                                     attribute:NSLayoutAttributeWidth
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:nil
                                                                     attribute:NSLayoutAttributeNotAnAttribute
                                                                    multiplier:1
                                                                      constant:200]];

これらの制約によってanotherモーダルの表示がハングする理由と、制約の1つのバリエーションの動作が大幅に異なる理由についてはまだ非常に混乱しています。その他。

20
Ben Packard

これが元の作成者の問題であるかどうかはわかりませんが、これが私にとって同様の問題を解決したものです。私はdidSelectRowAtIndexPathからのビューを提示しようとしていたので、以前はdeselectRowAtIndexPathに電話する必要がありました。これが誰かを助けるかもしれないなら...

54
vib

セットに対するいくつかの追加および削除操作のため、アプリが応答しません。メインスレッドで重い処理を行うと、アプリがブロックされて応答しなくなります。

簡単に言うと、セットにオブジェクトを追加するループがあり、メインスレッドでそれを実行しているため、アプリが遅くなっています。

楽器を見ると、ビューの読み込みボタンとレンダリングはかなり高速です。 initWithFrameの場合、viewDidLoadは全体の4%未満の時間しかかかりません。ほとんどの時間は、NSISVairableのリリースと保持に費やされます。これは約500回実行されます。つまり、コレクションオブジェクトを使用して何かを行っており、おそらくループ内にあります。保持と解放には時間がかかるため、メインスレッドで実行しないでください。

簡単な解決策は:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT、0)、^ {
 //ここですべての面倒な作業をバックグラウンドスレッドで実行します。
} 

次のコードが何も改善しないのはなぜですか?

 dispatch_async(dispatch_get_main_queue()、^ {
 SCAAboutController2 * controller = [[SCAAboutController2 alloc] initWithNibName:nil bundle:nil]; 
 UINavigationController * navController = [[UINavigationController all :controller]; 
 [self presentViewController:navControllerアニメーション:YEScompletion:nil]; 
}); 

あなたはすでにメインスレッドでこのようなことをしていて、バックグラウンドスレッドでmain_queueを呼び出す必要があるからです。バックグラウンドスレッドでUIを実行しないでください。

7
Kunal Balani

コールバックがメインスレッドとは異なるスレッドにある場合にも、同様の問題が発生しました。使用する

            DispatchQueue.main.async {
                 Your_UI_update_function()
            }

uIの更新が遅い問題を解決します。

3
Peter Pham

行の追加:

CFRunLoopWakeUp(CFRunLoopGetCurrent());

後:

[self presentViewController:navController animated:YES completion:nil];

私の問題を修正しました。

このスレッド からの回答。 Eugene H によるコメントのおかげで見つかりました。

3
MattL

私は答えを1年遅れて投稿していることを知っています。しかし、それが他の誰かに役立つなら。

(Swiftコード)を入れてみてください

self.view.layer.shouldRasterize = true;
self.view.layer.rasterizationScale = UIScreen.mainScreen().scale;

表示されているビューコントローラの場合(そこで機能しない場合は、親にも配置してみてください。両方に配置しましたが、他のすべてのアニメーションもスムーズにするのに役立ちます)

お役に立てれば。

0
Kunal