2013-04-17 46 views
6

Tôi đang cố triển khai các yêu cầu url không đồng bộ trong một hàm cụ thể, tôi muốn tất cả các yêu cầu này hoàn thành và sau đó thực hiện một hành động cụ thể nhưng hành động được đặt trước yêu cầu, nó được gọi trước khi yêu cầu hoàn tất .Yêu cầu url không đồng bộ bên trong dispatch_async

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];   
    } 
    } 

bây giờ cập nhậtUIFunction được gọi trước khi myAsyncMultipleURLRequestFunction hoàn thành tất cả yêu cầu. Cũng đã thử điều này với NSOperaitonQueue nhưng không thể làm những gì tôi thực sự muốn.

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

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

Tôi biết điều này rất đơn giản nhưng tôi sắp hết thời gian, mọi trợ giúp đều được đánh giá cao.

Trả lời

10

@tkanzakic này đang trên con đường đúng đắn. Cấu trúc đúng để sử dụng là dispatch_group_t. Nhưng việc thực hiện có thể được cải thiện. Bằng cách sử dụng semaphore, bạn có thể khởi chạy tất cả các tải xuống không đồng bộ và vẫn đảm bảo rằng bạn không có quá nhiều hoạt động đồng thời. Dưới đây là một mẫu mã minh họa cách bạn nên sử dụng dispatch_group_t cũng như thực hiện tất cả các tải xuống của mình song song:

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); 
+0

Tôi sẽ thử điều này, có vẻ đầy hứa hẹn. – satheeshwaran

+0

Ứng dụng có hoạt động cho bạn không? – aLevelOfIndirection

3

Bạn có thể tạo một dispatch_group_t và sau đó sử dụng dispatch_group_notify để thực hiện updateUIFunction khi khối trước đó của nhóm kết thúc hoạt động, ví dụ:

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]; 
     }); 
    }); 
}); 
+0

Cảm ơn bạn sẽ thử điều này và cho bạn biết! – satheeshwaran

+0

Hey @tkanzakic nó không hoạt động, giống như trước đây. updateUIFUnction được gọi trước khi myAsyncMultipleURLRequestFunction được hoàn thành. – satheeshwaran

+0

Tôi đã thực hiện một sửa đổi nhỏ của khối 'dispatch_group_notify', tôi nhớ rằng tôi cần phải thực hiện nó theo cách này là một số dự án, cung cấp cho nó một thử – tkanzakic

1

Đầu Cấu hình chạy vòng lặp.

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]]; 
    } 
}); 

Hãy thử

+0

ý của bạn là gì do self.finished ở đây ?? Nó là một BOOL ?? – satheeshwaran

Các vấn đề liên quan