iOS:RestKit 操作阻止在我想要的时候执行

标签 ios ipad grand-central-dispatch restkit-0.20

我正在使用 RestKit .20 映射两个对象。第二个对象依赖于第一个。因此第一个操作必须在第二个操作之前进行。操作完成后, Controller 使用模型对象在表格 View 中显示适当的信息。

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

这就是我想要发生的事情:

  1. View 加载并开始加载/映射第一个对象。
  2. 加载第一个对象后,将加载/映射第二个对象。
  3. 表格 View 重新加载。

这是发生了什么:

  1. 查看加载,加载 TableView 。
  2. 操作最后执行,每次执行 block 操作时都会重新加载数据 - 这不是我想要的解决方案,但这是我可以让它工作的唯一方法。

我很难解释,所以这里有一些代码:(我省略了一些不相关的代码)

- (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 服务重新加载/映射新数据,以便与重新加载表分开。

换句话说,这里最大的问题是:如何准确控制操作 block 的执行时间?

最佳答案

一种相当简单的方法是使用 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 作为一个方便的计数器,并具有附加功能,您可以设置一个 block ,以便在计数器下次达到零时执行。计数器从 0 开始。对于开始的每个第二个对象加载,您递增计数器(通过调用 dispatch_group_enter ),然后对于完成(或失败)的每个第二个对象加载,您递减计数器(通过调用 dispatch_group_leave )。当计数器达到 0 时,您用 dispatch_group_notify 设置的 block 将被执行(此时您可以知道所有第二个对象加载操作都已完成。)

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

关于iOS:RestKit 操作阻止在我想要的时候执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18631514/

相关文章:

iPhone 。按钮图像不切换

ios - SVProgressHud 等待时间过长才关闭

ios - Objective-C - 在继续之前等待另一个线程上的调用返回

ios - Grand Central Dispatch 嵌套队列和不同的队列优先级

ios - 不可能更改 UIBarButtonItem 标题?

ios - Apple Developer 和 Enterprise Programs 一起

ios - 关联类型 Swift 3

iphone - 1帧内使用opengl es在ipad上最多可以绘制多少个三角形?

ios - SBJson iOS 解析器方法已弃用?

ios - 带蓝牙条码扫描仪的 iPad 2