1

UITableViewDataSourcefromプロトコルとプロトコルを実装するカスタムViewControllerがありUITableViewDelegateます。(私のviewDidLoadメソッドで)テーブルのデータをロードするときに、aNSOperationQueueとaを作成し、NSInvocationOperationそれをキューに追加します。アクティビティインジケーターを表示してviewDidLoad終了します。

操作に使用されたメソッドは、アクティビティインジケーターのアニメーションを終了します。

NSLogでは操作のメソッドが返されたように見えますが、操作が完了すると、操作が実際に完了するまでに5〜7秒の休止があることに気付きました。

Instrumentsを使用して一時停止が発生している場所を特定しようとしましたが、CPU時間のほとんどがシステムライブラリに費やされているため、それからはわかりません。

編集 これは省略形です:

@implementation MyViewController
@synthesize ...

- (void)viewDidLoad {
    [super viewDidLoad];
    self.opsQueue = [[NSOperationQueue alloc] init];

    NSInvocationOperation *aiStartOp = [[[NSInvocationOperation alloc]
                                           initWithTarget:self
                                                 selector:@selector(showActivityIndicators)
                                                   object:nil] autorelease];
    [self.opsQueue addOperation:aiStartOp];

    NSInvocationOperation *dataOp = [[[[NSInvicationOperation alloc] 
                                         initWithTarget:self
                                               selector:@selector(dataUpdate)
                                                 object:nil] autorelease];
    [dataOp addDependency aiStartOp];
    [self.opsQueue addOperation:dataOp];

    NSInvicationOperation *aiStopOp = [[[NSInvicationOperation alloc]
                                          initWithTarget:self
                                                selector:@selector(hideActivityIndicators)
                                                  object:nil] autorelease];
    [aiStopOp addDependency:dataOp];
    [self.opsQueue addOperation:aiStopOp];
}

/* other stuff */

@end

明確にするために、キュー内の最後の操作は次のとおりです。

- (void)hideActivityIndicators {
    DLog(@"hiding activity indicator");
    self.portraitChartProgressView.hidden = YES;
    [self.portraitChartProgressIndicator stopAnimating];

    self.landscapeProgressView.hidden = NO;
    [self.landscapeProgressIndicator startAnimating];
}

ログに表示されるのは、上記のログメッセージの出力であり、その後5秒間休止し、最後にインジケーターが非表示になっているビューが続きます。

何か案は?

4

1 に答える 1

3

すべてのUIイベント、描画などはメインスレッドで実行する必要があります。次のようなものを使用して、呼び出しをメインスレッドに転送できます。

- (void)hideActivityIndicators {

    if (![NSThread isMainThread]) 
         [self performSelectorOnMainThread:@selector(hideActivityIndicators) withObject:nil waitUntilDone:NO];

    DLog(@"hiding activity indicator");
    self.portraitChartProgressView.hidden = YES;
    [self.portraitChartProgressIndicator stopAnimating];

    self.landscapeProgressView.hidden = NO;
    [self.landscapeProgressIndicator startAnimating];
}

編集"

もう少し注意深く見てみましょう。おそらく行う必要のないことの1つは、に追加して「読み込み中」のビューを開始および停止することNSOperationQueueです。おそらく、キューで行う必要があるのはデータの更新だけです。データ操作が完了したら、通知と委任を投稿してビューを更新します。

TopSongsサンプルプロジェクトは、これを非常によく示していますメインスレッドへの転送ステートメントは、サンプルのAppDelegate.mファイルのコードに基づいています。

于 2010-06-30T19:29:05.087 に答える