6

特定の関数に非同期 URL リクエストを実装しようとしています。これらのすべてのリクエストを完了してから特定のアクションを実行したいのですが、アクションがリクエストよりも優先されます。つまり、リクエストが完了する前に呼び出されます。

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL);
        dispatch_async(fetchQ, ^{
            [self myAsyncMultipleURLRequestFunction];
            dispatch_sync(dispatch_get_main_queue(), ^{
                [self updateUIFunction];
            });
        });

-(void)myAsyncMultipleURLRequestFunction
   {
    for (int i=0; i<count; i++) 
     {
     NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];          
     }
   }

myAsyncMultipleURLRequestFunction がすべてのリクエストを完了する前に updateUIFunction が呼び出されるようになりました。NSOperaitonQueue でもこれを試しましたが、本当にやりたいことができませんでした。

[_operationQ addOperationWithBlock: ^ {
     for (int i=0; i<count; i++)
      {
     NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];          
      }
    }

[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
         // updating UI
         [self updateUIFunction];
    }];
}];

私はこれが簡単であることを知っていますが、私は時間がなくなっています。

4

3 に答える 3

10

@tkanzakic は正しい道を進んでいます。使用する正しい構造は、dispatch_group_t です。しかし、実装は改善される可能性があります。セマフォを使用することで、すべてのダウンロードを非同期で開始できますが、同時に実行するものが多すぎないようにすることができます。これは、dispatch_group_t を使用してすべてのダウンロードを並列化する方法を示すコード サンプルです。

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL);
dispatch_group_t fetchGroup = dispatch_group_create();

// This will allow up to 8 parallel downloads.
dispatch_semaphore_t downloadSema = dispatch_semaphore_create(8);

// We start ALL our downloads in parallel throttled by the above semaphore.
for (int i=0; i<count; i++) {
    dispatch_group_async(fetchGroup, fetchQ, ^(void) {
        dispatch_semaphore_wait(downloadSema, DISPATCH_TIME_FOREVER);
        NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:requestArray[i] delegate:self];
        dispatch_semaphore_signal(downloadSema);
    });
}

// Now we wait until ALL our dispatch_group_async are finished.
dispatch_group_wait(fetchGroup, DISPATCH_TIME_FOREVER);

// Update your UI
dispatch_sync(dispatch_get_main_queue(), ^{
    [self updateUIFunction];
});

// Release resources
dispatch_release(fetchGroup);
dispatch_release(downloadSema);
dispatch_release(fetchQ);
于 2013-04-19T13:30:59.023 に答える
3

を作成してから、グループの前のブロックの実行が終了したときに を実行するためにdispatch_group_t使用できます。次に例を示します。dispatch_group_notifyupdateUIFunction

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL);
dispatch_async(fetchQ, ^{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        [self myAsyncMultipleURLRequestFunction];
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateUIFunction];
        });
    });
});
于 2013-04-17T07:48:18.747 に答える
1

最初に実行ループを構成します。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
    [NSURLConnection connectionWithRequest:request delegate:self];
    while(!self.finished) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
});

これを試して

于 2013-04-17T08:07:49.237 に答える