0

基本上我想要一种在循环中多次发出 NSURLRequest 直到满足某个条件的方法。我正在使用休息 api,但休息 api 一次最多只能允许 1,000 个结果。因此,如果我有,假设总共有 1,500 个,我想请求获得前 1,000 个,然后我需要通过另一个几乎完全相同的请求来获得其余的,除了 startAt: 参数不同(所以我可以从 1001 到 1500 .我想在一个while循环中设置它(当我完成加载所有数据时)并且正在阅读有关信号量但它没有像我预期的那样工作。我不知道我有多少结果直到我发出第一个请求。可能是 50、1000 或 10,000。

这是代码:

while(!finishedLoadingAllData){
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

        NSURLRequest *myRequest = [self loadData: startAt:startAt maxResults:maxResults];

        [NSURLConnection sendAsynchronousRequest:myRequest
                                           queue:[NSOperationQueue mainQueue]
                               completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                                   if(error){
                                       completionHandler(issuesWithProjectData, error);
                                   }
                                   else{
                                       NSDictionary *issuesDictionary = [[NSDictionary alloc] initWithDictionary:[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error]];
                                       [issuesWithProjectData addObjectsFromArray:issuesDictionary[@"issues"]];

                                       if(issuesWithProjectData.count == [issuesDictionary[@"total"] integerValue]){
                                           completionHandler([issuesWithProjectData copy], error);
                                            finishedLoadingAllData = YES;
                                       }
                                       else{
                                           startAt = maxResults + 1;
                                           maxResults = maxResults + 1000;
                                       }
                                   }
                                   dispatch_semaphore_signal(semaphore);
                               }];

        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }

基本上我想让while循环一直等到完成块完成。然后,只有这样,我才希望 while 循环检查我们是否拥有所有数据(如果没有,则使用更新的 startAt 值/maxResults 值发出另一个请求。

现在它只是挂在dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

我做错了什么或者我需要做什么?也许信号量是错误的解决方案。谢谢。

4

3 回答 3

0

好的。我看的越多,我就越认为用信号量来解决这个问题不是一个坏主意,因为另一种方法是有一个串行队列等,而这个解决方案并不是那么复杂。
问题是,您要求在主线程上运行完成处理程序

[NSURLConnection sendAsynchronousRequest:myRequest
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 

并且您可能正在主线程中创建 NSURL 请求。因此,当它等待信号量在主线程上释放时,NSURL 完成处理程序正在等待主线程摆脱其当前的运行循环。

所以创建一个新的操作队列。

于 2015-06-04T02:51:19.840 回答
0

做这样的事情会不会更容易:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //run on a background thread

    while(!finishedLoadingAllData){

        NSURLRequest *myRequest = [self loadData: startAt:startAt maxResults:maxResults];
        NSHTTPURLResponse *response = nil;
        NSError *error = nil;

        NSData *responseData = [NSURLConnection sendSynchronousRequest:myRequest returningResponse:&response error:&error]; //blocks until completed

        if(response.statusCode == 200 && responseData != nil){ //handle response and set finishedLoadingAllData when you want
            //do stuff with response
            dispatch_sync(dispatch_get_main_queue(), ^{
                 //do stuff on the main thread that needs to be done
        }
    }
});
于 2015-06-04T05:06:30.383 回答
0

请不要那样做..NSURLConnection sendAsynchronousRequest如果您的数据是块状的,它将为您循环加载..试试这个..

__block NSMutableData *fragmentData = [NSMutableData data];

[[NSOperationQueue mainQueue] cancelAllOperations];

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{ 
    [fragmentData appendData:data];

    if ([data length] == 0 && error == nil)
     {
         NSLog(@"No response from server");
     }
     else if (error != nil && error.code == NSURLErrorTimedOut)
     {
         NSLog(@"Request time out");
     }
     else if (error != nil)
     {
         NSLog(@"Unexpected error occur: %@", error.localizedDescription);
     }
     else if ([data length] > 0 && error == nil)
     {
         if ([fragmentData length] == [response expectedContentLength])
         {
             // finished loading all your data
         }
     }
 }];

我已经从服务器处理方法创建了两个厚实的 json 响应.. 其中之一就是这个,所以希望这对你也有用.. 干杯!;)

于 2015-06-04T05:46:54.600 回答