1

iOS5 では JSON をダウンロードしてすべてバックグラウンドで処理する必要があるため、メイン スレッドがフリーズすることはありません。私はそれを行うことに成功していません。

これが私がやっていることです:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self performSelectorOnMainThread:@selector(processTheData:)
                           withObject:myData
                        waitUntilDone:YES];
}); 

-(void)processTheData:(NSData *)data
{
    //Parse JSON here
}

上記のコードでは、ダウンロードが完了したら、Main thrd で処理します。データを取得したことがわかっているときにバックグラウンドで実行するにはどうすればよいですか?

4

1 に答える 1

7

典型的なパターンは次のとおりです。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self processTheData:myData];
    });
}); 

または、processTheDataそれ自体はUIの更新を行わないが、完了したときに更新したい場合、一般的なアプローチは、ユーザーインターフェイスを更新する必要があるまでメインキューにディスパッチしないことです。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self processTheData:myData];

    dispatch_async(dispatch_get_main_queue(), ^{
        // code that updates UI goes here
    });
}); 

最後に、上記のコードを少数呼び出している場合は問題ありませんが、多くのリクエストを行う可能性がある場合は、サーバーの数が多いと、受け入れる同時リクエストの数が制限されることに注意してください。特定のクライアントから。サーバーがそうでない場合でも、とにかくサーバーに対して行う同時リクエストの数を制限する必要があります。NSOperationQueueGCDの代わりに使用すると、これを簡単に行うことができます。

したがって、複数の非同期リクエストを実行している場合は、おそらく次のことを実行する必要があります(2番目の例をモデルとして使用)。まず、リクエストの開始を開始する前に、NSOperationQueueオブジェクトを作成する必要があります。

@property (nonatomic, strong) NSOperationQueue *queue;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.queue = [[NSOperationQueue alloc] init];
    self.queue.maxConcurrentOperationCount = 4;
}

次に、個々の非同期リクエストを実行する必要があるコードは次のようになります。

[self.queue addOperationWithBlock:^{

    NSURL *url = [NSURL URLWithString:myURL];
    myData = [NSData dataWithContentsOfURL:url];

    [self processTheData:myData];

    [[NSOperationQueue mainQueue] addOperationWithBlock:{
        // code that updates UI goes here
    }];
}]; 
于 2013-01-26T16:52:21.603 に答える