【问题标题】:Is it possible in Objective-C to call a method after a set of other methods are finished executing在Objective-C中是否可以在一组其他方法执行完毕后调用一个方法
【发布时间】:2014-08-23 20:11:11
【问题描述】:

这可能是一个有点幼稚的问题,但在我加载 ViewController 时,我正在使用一组方法(如下面的 getEachItem)加载应用程序所需的所有内容。这通常是 2 或 3 个项目,它们都被写入缓存。

我想调用在 getEachItem 的最终实例完成后运行的方法“showNavigation”,但不确定如何执行此操作。 getEachItem 使用 AFNetworking 执行 GET 请求。类似于 jQuery 完整块的东西,但对于下面的 for 循环的全部内容。

NSArray *tmpItems=[result objectForKey:@"ipad_items"];
for(NSDictionary *m in tmpItems){
  // will also increment into the _menus array
  [self getEachItem:[m objectForKey:@"id"]];
  [self getImages:[m objectForKey:@"id"]];
}
[self showNavigation];

【问题讨论】:

    标签: ios objective-c block afnetworking afnetworking-2


    【解决方案1】:

    当您调用 AFNetworking GET 方法时,它会返回一个 AFHTTPRequestOperation(一个 NSOperation 子类)。您可以利用这一事实为您的问题采用基于操作队列的解决方案。也就是说,您可以创建一个新的“完成操作”,它依赖于特定 AFNetworking 操作的完成。

    例如,您可以更改getEachItem 方法以返回GET 方法返回的AFHTTPRequestOperation。例如,假设您有一个getEachItem,当前定义如下:

    - (void)getEachItem:(id)identifier
    {
         // do a lot of stuff
    
         [self.manager GET:... parameters:... success:... failure:...];
    }
    

    将其更改为:

    - (NSOperation *)getEachItem:(id)identifier
    {
        // do a lot of stuff
    
        return [self.manager GET:... parameters:... success:... failure:...];
    }
    

    然后,您可以创建自己的完成操作,该操作将依赖于所有其他 AFHTTPRequestOperation 操作的完成。因此:

    NSOperation *completion = [NSBlockOperation blockOperationWithBlock:^{
        [self showNavigation];
    }];
    
    NSArray *tmpItems=[result objectForKey:@"ipad_items"];
    for(NSDictionary *m in tmpItems){
        // will also increment into the _menus array
        NSOperation *operation = [self getEachItem:[m objectForKey:@"id"]];
        [completion addDependency:operation];
        [self getImages:[m objectForKey:@"id"]];
    }
    
    [[NSOperationQueue mainQueue] addOperation:completion];
    

    完成此操作后,在所有 getEachItem 操作完成之前,completion 操作将不会触发。请注意,此完成操作将在核心 AFHTTPRequestOperation 对象完成时触发,但不能保证这些请求的相应完成块一定完成。


    另一种方法是使用 GCD“组”。使用这种技术,您在提交每个请求时“进入”组,然后在 GET 方法的完成块中“离开”组。然后,您可以指定当该组通知您离开该组的次数与您进入该组的次数一样多时要执行的代码块(即所有 AFNetworking 网络请求及其success/failure块,完成)。

    例如,给getEachItem添加一个dispatch_group_t参数:

    - (void)getEachItem:(id)identifier group:(dispatch_group_t)group
    {
        dispatch_group_enter(group);
    
        // do a lot of stuff
    
        [self.manager GET:... parameters:... success:^(...) {
            // do you success stuff and when done, leave the group
    
            dispatch_group_leave(group);
        } failure:^(...) {
            // do you failure stuff and when done, leave the group
    
            dispatch_group_leave(group);
        }];
    }
    

    注意,您在提交请求之前“进入”组,两个successfailure 块必须调用dispatch_group_leave

    完成此操作后,您现在可以在请求循环中使用 dispatch_group_t,当组收到所有已完成的通知时执行 showNavigation

    dispatch_group_t group = dispatch_group_create();
    
    NSArray *tmpItems=[result objectForKey:@"ipad_items"];
    for(NSDictionary *m in tmpItems){
        // will also increment into the _menus array
        [self getEachItem:[m objectForKey:@"id"] group:group];
        [self getImages:[m objectForKey:@"id"]];
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [self showNavigation];
    });
    

    【讨论】:

      猜你喜欢
      • 2014-03-21
      • 1970-01-01
      • 2018-10-30
      • 1970-01-01
      • 2012-02-24
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多