2

インターフェイスの更新を管理するための一般的でエレガントな方法を探しています。ユーザー インターフェイス コードはメイン スレッドで実行する必要があることはわかっているので、ネットワーク タスクで計算が必要な場合は、次のパターンで GDC を使用します。

dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(aQueue, ^() {

//Backgroud code

    dispatch_sync(dispatch_get_main_queue(), ^{
    //Update the UI
    }
}

このコードの問題は、計算中にユーザーがビューを変更したかどうかを常に確認する必要があるため、コードは次のようになります。

dispatch_sync(dispatch_get_main_queue(), ^{
    if (mylabel != nil)  && ([mylabel superview] != nil) {
        mylabel.text = _result_from_computation_;
    }
}

いくつかの最良の方法はありますか?

ありがとう。

4

2 に答える 2

1

あなたはかなりそれを持っています。ただし、さらに読みたい場合や、何が起こっているのかについてより完全な説明が必要な場合は...

Apple Docs Grand Central Dispatch (GCD) Referenceを読んで、WWDC 2012 のビデオセッション 712 - Asynchronous Design Patters with Blocks, GCD and XPC をご覧ください

iOS を使用している場合、XPC (プロセス間通信) は現在の OS バージョン (この記事の執筆時点では 6.1) でサポートされていないため、無視できます。

例:背景に大きな画像を読み込み、完成したら画像をセットする。

@interface MyClass ()
@property (strong) dispatch_block_t task;
@end

@implementation MyClass
- (void)viewDidLoad {
    self.task = ^{
        // Background Thread, i.e., your task
        NSImage *image = [[NSImage alloc] initWithData:data];
        dispatch_async(dispatch_get_main_queue(), ^{
            // Main Thread, setting the loaded image
            [view setImage:image];
        });
    });
}

- (IBAction)cancelTaskButtonClick:(id)sender {  // This can be -viewWillDisappear
    self.task = nil;  // Cancels this enqueued item in default global queue
}

- (IBAction)runTaskButtonClick:(id)sender {
    // Main Thread
    dispatch_queue_t queue;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, self.task);
}

後でインターフェイスをキャンセルしてリロードするには、dispatch_block_t 変数を nil に設定するだけです。

おそらくより具体的には、このコード例では、ディスクまたはネットワークからのデータの読み取りを扱います。

通常、基本的にバックグラウンド スレッドを取得し、タスクを実行し、完了時に別のブロックを呼び出してメイン スレッドを取得し、UI を更新する Call-Callback パターンを使用します。

お役に立てれば!

于 2013-02-01T09:21:55.420 に答える
0

ビューウィンドウのプロパティを確認できます:

if (myLabel.window) {
  // update label
}

if (label != nil)label が nil の場合、すべての label プロパティも nil (またはゼロ) になり、それらを設定しても例外が発生しないため、これは冗長です。

于 2013-02-01T07:55:25.230 に答える