Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 目标C:等待执行';而';循环,直到NSURLConnection请求完成_Ios_Objective C_Nsurlconnection_Semaphore_Sendasynchronousrequest - Fatal编程技术网

Ios 目标C:等待执行';而';循环,直到NSURLConnection请求完成

Ios 目标C:等待执行';而';循环,直到NSURLConnection请求完成,ios,objective-c,nsurlconnection,semaphore,sendasynchronousrequest,Ios,Objective C,Nsurlconnection,Semaphore,Sendasynchronousrequest,基本上,我想要一种在循环中多次发出NSURLRequest的方法,直到满足某个条件为止。我使用的是RESTAPI,但RESTAPI一次最多只允许1000个结果。因此,如果我有,比如说总共1500个,我想请求获得前1000个,然后我需要用另一个几乎完全相同的请求获得其余的,除了startAt:参数不同(因此我可以从1001到1500。我想在while循环中设置它(当我加载完所有数据时)我只是读了一些关于信号量的文章,但它并没有像我预期的那样工作。我不知道我有多少结果,直到我提出第一个请求。它可能是

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

代码如下:

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\u semaphore\u wait上(semaphore,dispatch\u TIME\u ever)


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

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

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

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

因此,创建一个新的操作队列。

这样做是否更容易:

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

请不要这样做。
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响应..其中一个是这个,希望这对您也有用..干杯!!;)

请不要这样做。在这种情况下,只有1个块等待完成NSURL请求,您不需要信号量。如果您想使用它,请尝试dispatch\u semaphore\u t semaphore=dispatch\u semaphore\u create(1);“我做错了什么?”.一切。不要等待。不要阻止。不要循环。不要信号。只需理解异步网络,按照你的方式做事。@matt-那么如果我不能循环,我该如何多次(未知次数)发出请求?我必须知道何时完成(从而获得所有数据)在我调用自己的内部完成块执行之前。您可以维护一个状态变量,并在完成处理程序中继续或不继续以获取下一个片段。这与任何后续下载情况都没有区别。感谢您的响应。使用[NSOperationQueue new]时与mainQueue相反,它似乎对我很好。但我看到nhgrif和matt基本上都说不要这样做。所以@lead_the_the_zeppelin..想法?我不会做无限while循环。信号量是可以的。只要用NSOperationQueue替换while循环,用一个在完成时调用自身的完成处理程序就可以了。像这样的事情是没有的如果finishedLoadingAllData为YES,则while循环将退出。在我的示例中,您是否介意展示如何使用NSOperationQueue的语法?