使3“for”循环等待异步回答。 obj-c ios

时间:2016-06-23 13:40:14

标签: objective-c

我正在开发适用于iPad iOS 8的应用程序,我需要让我的应用程序等待答案:

[directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {}]

此方法位于3个循环内。我尝试了dispatch_semaphore_t,但应用程序无法在此行之后继续:

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

然后卡住了。我尝试了dispatch_group_t并获得了相同的结果。 我想我做错了什么,但我不知道是什么。我试图搜索SO以寻找类似的问题但却一无所获。有人可以解释我是如何做到这一点的吗?

-(void)setTimesMissions {

for (Driver *d in self.dataList) {

    for (Period *p in d.periods) {

            for (Mission *m in p.missions) {

                MKDirections *directions = ....

                    // HERE i want the for loop stop until this completionHandler finish
                    [directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {

                        //and when he finish here continue
                    }];
            }
        }
}

}

1 个答案:

答案 0 :(得分:3)

在dispatch_async块中调用您的方法。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [youClassInstance setTimesMissions];
});

在循环中使用dispatch_semaphore_wait

- (void)setTimesMissions {
    Mission *home = [[Mission alloc]init];
    Mission *next = [[Mission alloc]init];
    for (Driver *d in self.dataList) {

        home.clientLat = d.centralPointLat;
        home.clientLon = d.centralPointLon;
        home.clientPaddres = d.centralAddress;

        for (Period *p in d.periods) {

            home.times = [[NSMutableArray alloc]init];

            if ([p.periodIx isEqualToString:self.thisPeriodIX]) {

                for (Mission *m in p.missions) {

                    Mission *source = home;
                    Mission *destination = m ;
                    MKPlacemark *placemarkSource = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake([source.clientLat doubleValue], [source.clientLon doubleValue]) addressDictionary:nil] ;
                    MKMapItem *mapItemSource = [[MKMapItem alloc] initWithPlacemark:placemarkSource];

                    MKPlacemark *placemarkDestination = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake([destination.clientLat doubleValue], [destination.clientLon doubleValue])addressDictionary:nil] ;
                    MKMapItem *mapItemDestination = [[MKMapItem alloc] initWithPlacemark:placemarkDestination];

                    MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init];
                    [directionsRequest setSource:mapItemSource];
                    [directionsRequest setDestination:mapItemDestination];
                    directionsRequest.transportType = MKDirectionsTransportTypeAutomobile;
                    [directionsRequest setRequestsAlternateRoutes:NO];
                    MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];

                    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
                    __block double timeTo;

                    [directions calculateETAWithCompletionHandler:^(MKETAResponse *response, NSError *error) {

                        if ( response.expectedTravelTime) {
                            timeTo = response.expectedTravelTime;
                            double ans = timeTo;
                            Time *t = [[Time alloc]init];
                            t.ix = m.serviceIX;
                            t.time = ans;
                            [home.times addObject:t];
                        }

                        dispatch_semaphore_signal(semaphore);
                    }];

                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                }

                 dispatch_async(dispatch_get_main_queue(), ^{
                      // code that should be executed on main queue 
                 });


                if (next.clientPaddres) {
                    home = next;
                }
            }
        }        
    }
}