【问题标题】:Cycle of asynchronous network tasks (Next executed after completion of previous one)异步网络任务循环(前一个完成后执行下一个)
【发布时间】:2016-01-20 15:01:09
【问题描述】:

我需要执行任务,以便在完成前一个任务后执行以下任务。

这是我的代码:

[self startLoading];
NSMutableArray *failedContainerRequests = [NSMutableArray new];
MyContainersViewController __weak *weakSelf = self;
[[RuzaServerAPI newAPIObject] serverGetListOfContainersWithSuccess:^(NSArray *containers) {
    dispatch_group_t downloadGroup = dispatch_group_create();
    for (RZContainerModel *containerModel in containers) {
        NSLog(@"Start container %@ with id %@", containerModel.containerName, containerModel.containerID);
        dispatch_group_enter(downloadGroup);
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [[RuzaServerAPI newAPIObject] serverGetListOfProductsInContainer:containerModel.containerID withSuccess:^(NSArray *products) {
                if (products.count > 0) {
                    containerModel.products = [NSMutableArray arrayWithArray:products];
                    NSMutableArray *imagesURLs = [NSMutableArray new];
                    for (RZProductModel *productModel in products) {
                        if (productModel.frontImageUrl) {
                            [imagesURLs addObject:productModel.frontImageUrl];
                        }

                        if (productModel.backImageUrl) {
                            [imagesURLs addObject:productModel.backImageUrl];
                        }
                    }

                    [self addImagesToDownloadQueue:imagesURLs.copy withComplection:^(BOOL status) {
                        [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) {
                            NSLog(@"Container %@ succesfully saved!", containerModel.containerName);
                            dispatch_semaphore_signal(semaphore);
                            dispatch_group_leave(downloadGroup);
                        }];
                    }];
                } else {
                    [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) {
                        NSLog(@"Container %@ succesfully saved!", containerModel.containerName);
                        dispatch_semaphore_signal(semaphore);
                        dispatch_group_leave(downloadGroup);
                    }];
                }
            } failure:^(NSError *error) {
                NSLog(@"Container %@ failed!\n%@", containerModel.containerName, error.localizedDescription);
                [failedContainerRequests addObject:containerModel];
                dispatch_semaphore_signal(semaphore);
                dispatch_group_leave(downloadGroup);
                //                    dispatch_async(dispatch_get_main_queue(), ^{
                //                        // Error message!
                //                    });
            }];
        });
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    }

    dispatch_group_notify(downloadGroup, dispatch_get_main_queue(),^{
        [weakSelf stopLoading];

        for (RZContainerModel *containerModel in failedContainerRequests) {
            NSLog(@"Container %@", containerModel.containerName);
        }

    });
} failure:^(NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf stopLoading];
        NSString *messageStr = [NSString stringWithFormat:@"%@\nПопробовать еще раз?", error.localizedDescription];
        LGAlertView *allert = [[LGAlertView alloc] initWithTitle:@"Ошибка"
                                                         message:messageStr
                                                           style:LGAlertViewStyleAlert
                                                    buttonTitles:@[ @"ОК" ]
                                               cancelButtonTitle:@"Отмена"
                                          destructiveButtonTitle:nil
                                                   actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) {
                                                       [weakSelf getListOfContainers];
                                                   }
                                                   cancelHandler:nil
                                              destructiveHandler:nil];
        [allert showAnimated:YES completionHandler:nil];
    });
}];

我尝试对此进行调试,但信号量之后的操作从未执行。

谁能帮助我?谢谢。

【问题讨论】:

    标签: ios multithreading grand-central-dispatch deadlock semaphore


    【解决方案1】:

    我能够解决我的问题。我发布代码,也许它会对某人有用。

    [self startLoading];
    NSMutableArray *failedContainerRequests = [NSMutableArray new];
    MyContainersViewController __weak *weakSelf = self;
    [[RuzaServerAPI newAPIObject] serverGetListOfContainersWithSuccess:^(NSArray *containers) {
        dispatch_group_t downloadGroup = dispatch_group_create();
        dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
        dispatch_async(queue, ^{
            for (RZContainerModel *containerModel in containers) {
                NSLog(@"Start container %@ with id %@", containerModel.containerName, containerModel.containerID);
                dispatch_group_enter(downloadGroup);
                dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    
                [[RuzaServerAPI newAPIObject] serverGetListOfProductsInContainer:containerModel.containerID withSuccess:^(NSArray *products) {
                    NSLog(@"Container %@ succesfully downloaded!", containerModel.containerName);
                    if (products.count > 0) {
                        containerModel.products = [NSMutableArray arrayWithArray:products];
                        NSMutableArray *imagesURLs = [NSMutableArray new];
                        for (RZProductModel *productModel in products) {
                            if (productModel.frontImageUrl) {
                                [imagesURLs addObject:productModel.frontImageUrl];
                            }
    
                            if (productModel.backImageUrl) {
                                [imagesURLs addObject:productModel.backImageUrl];
                            }
                        }
    
                        [self addImagesToDownloadQueue:imagesURLs.copy withComplection:^(BOOL status) {
                            [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) {
                                NSLog(@"Container %@ succesfully saved!", containerModel.containerName);
                                dispatch_semaphore_signal(semaphore);
                                dispatch_group_leave(downloadGroup);
                            }];
                        }];
                    } else {
                        [[RZCoreDataManager sharedInstance] saveContainer:containerModel withCompletion:^(BOOL success) {
                            NSLog(@"Container %@ succesfully saved!", containerModel.containerName);
                            dispatch_semaphore_signal(semaphore);
                            dispatch_group_leave(downloadGroup);
                        }];
                    }
                } failure:^(NSError *error) {
                    NSLog(@"Container %@ failed!\n%@", containerModel.containerName, error.localizedDescription);
                    [failedContainerRequests addObject:containerModel];
                    dispatch_semaphore_signal(semaphore);
                    dispatch_group_leave(downloadGroup);
                    //                    dispatch_async(dispatch_get_main_queue(), ^{
                    //                        // Error message!
                    //                    });
                }];
                dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            }
    
            dispatch_group_notify(downloadGroup, dispatch_get_main_queue(),^{
                [weakSelf stopLoading];
            });
        });
    } failure:^(NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf stopLoading];
            NSString *messageStr = [NSString stringWithFormat:@"%@\nПопробовать еще раз?", error.localizedDescription];
            LGAlertView *allert = [[LGAlertView alloc] initWithTitle:@"Ошибка"
                                                             message:messageStr
                                                               style:LGAlertViewStyleAlert
                                                        buttonTitles:@[ @"ОК" ]
                                                   cancelButtonTitle:@"Отмена"
                                              destructiveButtonTitle:nil
                                                       actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) {
                                                           [weakSelf getListOfContainers];
                                                       }
                                                       cancelHandler:nil
                                                  destructiveHandler:nil];
            [allert showAnimated:YES completionHandler:nil];
        });
    }];
    

    【讨论】:

      猜你喜欢
      • 2015-03-04
      • 1970-01-01
      • 2019-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 1970-01-01
      • 2018-04-10
      相关资源
      最近更新 更多