我正在使用RestKit .20映射两个对象。第二个对象取决于第一个。因此,第一个操作必须在第二个操作之前进行。操作完成后,控制器将使用模型对象在表格视图中显示适当的信息。

第一个对象具有唯一的ID,该ID用于形成url请求的一部分,以获取附加到其的对象。它的所有工作和请求都在获取信息并正确执行映射,但是操作的所有操作都是错误的,我只是无法解决!

这就是我想发生的事情:


查看加载并开始加载/映射第一个对象。
一旦第一个对象被加载,第二个对象被加载/映射。
表格视图重新加载。


继承人发生了什么:


视图加载,加载表视图。
操作最后执行一次,每执行一次块操作便重新加载数据-不是我想要的解决方案,而是我能使其正常工作的唯一方法。


这让我很难解释,因此这里有一些代码:(我省略了无关代码的分配)

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self loadFirstObjects];
    //omitted code

}



- (void)loadFirstObjects {
    //omitted code

    [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        self.pubRepos = mappingResult.array;
        [self loadSecondaryObjects];
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        NSLog(@"ERROR: %@", error);
    }];

    [operation start];
}

- (void)loadSecondObjects
{
    for (FirstObject *firstObject in firstObjects) {

        //Omitted code

        [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
            SecondObject *secondObject = [mappingResult.array objectAtIndex:0];

            [secondObjects setObject:secondObject forKey:secondObject.idNum];
            [table reloadData];
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"ERROR: %@", error);
        }];

        [operation start];

    }
}


那么,如何以所需的方式工作呢?我希望能够先执行请求/映射,然后将所有信息加载到表中并进行更新。我需要不断地从Web服务重新加载/映射新数据,以便与重新加载表分开。

所以换句话说,这里最大的问题是:如何精确地控制何时执行操作块?

最佳答案

一种很容易做到这一点的方法是使用dispatch_group。您的-loadSecondObjects方法可能如下所示:

- (void)loadSecondObjects
{
    dispatch_group_t group = dispatch_group_create();

    for (FirstObject *firstObject in firstObjects) {
        // Omitted code
        dispatch_group_enter(group);
        [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
            SecondObject *secondObject = [mappingResult.array objectAtIndex:0];
            [secondObjects setObject:secondObject forKey:secondObject.idNum];
            dispatch_group_leave(group);
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"ERROR: %@", error);
            dispatch_group_leave(group);
        }];

        [operation start];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [table reloadData];
    });
}


本质上,这里发生的事情是您将dispatch_group用作具有方便功能的计数器,并具有添加的功能,您可以设置一个块以在计数器下一个达到零时执行。计数器从0开始。对于您开始的每个第二对象加载,您都增加计数器(通过调用dispatch_group_enter),然后对于完成(或失败)的每个第二对象负载,计数器都减小(通过调用)。当计数器达到0时,将执行您使用dispatch_group_leave设置的块(并且您那时可以知道所有第二个对象加载操作均已完成。)

PS:由于在您的代码中没有看到任何保留/释放请求,因此我假设您正在使用ARC。如果不是,则需要dispatch_group_notify该组。

10-08 05:56
查看更多