带有UIActivityIndi​​cator的UIAlertView显示太晚/线程问题

时间:2011-10-17 20:34:39

标签: iphone objective-c ios multithreading nsoperation

在我的应用程序中,我有几个地方,我正在调用Web服务并检索JSON,然后将其解析为对象数组。耗时的部分绝对是Web服务调用。我想要的行为如下:

  1. 用户选择感兴趣的行
  2. 在当前视图中,添加了ActivtiyIndi​​cator子视图的AlertView
  3. 新VC中的数据加载
  4. 出现新视图
  5. AV指标不见了
  6. 我的VC配备了doLoadData方法,基本上可以加载每个VC显示的数据数组。例如:

    AnimalViewController有一个按钮“View Dogs”按下时按下:

    DogViewController *vc = [[DogViewController alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
    [vc release];

    DogViewController有属性NSArray *dogs和方法doLoadDogs,需要一段时间才能完成。

    目前我有“查看狗”的方法:

    1. 使用ActivityIndi​​cator创建AlertView
    2. 显示
    3. 创建VC
    4. 推送
    5. 隐藏AlertView
    6. 发布并且没有
    7. 这似乎并不困难,但我还没有通过线程找到一个简单的实现。

1 个答案:

答案 0 :(得分:1)

如果你的网络调用/数组创建需要很长时间并且在主线程上,那么所有这些基本上都会同时发生。当您执行诸如显示警报视图,推送导航控制器等操作时,您真正要做的就是在运行循环的下一轮安排这些事情发生。由于你的“View Dogs”方法基本上会阻塞,直到完成所有操作,因此在需要一切之后才会再次执行运行循环。

最佳解决方案是分解网络加载代码,而不是阻止主线程/主事件循环。作为一个快速解决方案,您可以使用GCD分解当前“查看狗”方法的各个部分。作为一个例子(显然这需要根据您的实际要求/代码更新):

- (void)viewDogs:(id)sender
{
  dispatch_queue_t mainQueue = dispatch_get_main_queue();
  // create and schedule the alert view
  UIAlertView* alert = [[UIAlertView alloc] initWithTitle...]; // your real alert view
  dispatch_async(mainQueue, ^{ [alert show]; });
  dispatch_async(mainQueue, ^{
    DogViewController* vc = [[DogViewController alloc] init];
    [[self navigationController] pushViewController:vc animated:YES];
    [vc release];
    dispatch_async(mainQueue, ^{ [alert dismissWith...]; [alert release]; });
  });
}