0

NSTimer/NSOperationQueue の実行に一貫性がないという UI の問題を解決しようとしています。NSTimer または NSInvocationOperation を使用して以下のコードをトリガーするかどうかに関係なく、多くの場合、必要に応じてパフォーマンスが向上しますが、動作が遅くなることが何度かあります (また、以下の例のように、コードが 1 秒以上実行される場合もあります) )。

NSInvocationOperation を介して呼び出される私のコードは次のとおりです。

-(void) progressAsynch{
    for (count = 1; count<=100; count++) {

        // Reposition Label's CGRect.
        [self performSelectorOnMainThread:@selector(moveLabelToNewPosition) withObject:nil waitUntilDone:YES];

        //Update the progress of the progress view
        [self performSelectorOnMainThread:@selector(advanceProgressViewProgress) withObject:nil waitUntilDone:YES];

        //Sleep for 10 millisecs
        [NSThread sleepForTimeInterval:0.01];

        //if the progress view has progressed fully call main thread to to next tasks.
        if(progressView.progress == 1) {
            [self performSelectorOnMainThread:@selector(processResult) withObject:nil waitUntilDone:YES];
        }
    }

}

NSTimer (10 ミリ秒ごとにトリガー) によって呼び出されるメソッドのコードは、上記と非常に似ていますが、for ループが含まれていないという点だけです。

明らかに、この処理の外部に、このパフォーマンスを頻繁に低下させている何かがあるようです。

同様の問題を抱えているかどうか、または私を助ける可能性のあるポインター/ヒントがあるかどうかを知りたい.

前もって感謝します..

4

1 に答える 1

0

スレッド間通信はそれほど高速ではなく、waitUntilDone:YES追加のスレッド同期オーバーヘッドが追加され、完全に不要です (私は performSelectors がシリアル化されていると確信しています)。次のようなことをすると運が良くなるかもしれません

-(void) progressAsynch{
    for (count = 1; count<=100; count++) {
        [self performSelectorOnMainThread:@selector(stuff) withObject:nil waitUntilDone:NO];
        [NSThread sleepForTimeInterval:0.01];
    }
}

しかし、これはまだ悪いです。selfNSInvocation によって保持され、おそらくバックグラウンド スレッドで解放されるビューまたはビュー コントローラーのようです。UIKit のほとんどはスレッドセーフではありません。Game Center のサンプル コードでは、 UIKitクラスはスレッド セーフではない可能性があるため、リリースによって が発生する可能性があるため、UIKit クラスをバックグラウンド スレッドでリリースしてはならないことを-dealloc強調しています。(痛い)

progressView.progress(また、バックグラウンド スレッドからの呼び出しは安全ではないことに注意してください。)

また、可能なことの限界に達しています。iOS タイムスライスは 10 ミリ秒であると確信しています。これは、他の何かが任意の時点で CPU を必要とする場合 (そして多くのバックグラウンド プロセスがあることを意味します。アクティビティ モニターを使用してみてください。楽器によっては) アニメーションが遅れて見える場合があります。

最後に、いくつかのオーディオ再生コードを使用して、NSTimer があまり正確ではないことに気付きました。理由はわかりません。SIGALRM を使用する何かで修正したと思います (そして、おそらくシグナルセーフではないコードです)。

ディスプレイのリフレッシュ レートと同期され (合格だと思います[UIScreen mainScreen])、アニメーションで使用するように設計されている CADisplayLink を使用すると、運が良くなる可能性があるため、パフォーマンスが少し向上するはずです。iOS 3.1+ ですが、3.0 をサポートする意味はほとんどないと思います。

于 2011-06-30T02:42:48.020 に答える