我正在使用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
该组。