在Web服务调用期间,UIActivityIndi​​catorView不再出现

时间:2014-05-12 16:30:48

标签: ios objective-c uiactivityindicatorview

昨天我在我的iOS应用程序中添加了UIActivityIndicatorView,一切都很好,现在我正在尝试运行相同的应用程序,但UIActivityIndicatorView不再显示了agenda视图(调用Web服务)需要很长时间(超过昨天)才会出现,而且通常根本不显示。我该如何解决这个问题?这是我的代码:

- (IBAction)agenda:(id)sender {

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spinner.center = CGPointMake(160, 240);
    spinner.hidesWhenStopped = YES;
    [self.view addSubview:spinner];
    [spinner startAnimating];
    // how we stop refresh from freezing the main UI thread
    dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL);
    dispatch_async(downloadQueue, ^{

        // do our long running process here
        // [NSThread sleepForTimeInterval:10];
        AgendaViewController *agenda = [[ AgendaViewController alloc] initWithNibName:nil bundle:nil];

        // do any UI stuff on the main UI thread
        dispatch_async(dispatch_get_main_queue(), ^{

            [spinner stopAnimating];
            [self.navigationController pushViewController:agenda animated:YES];           
        });

    });
    dispatch_release(downloadQueue);

}

2 个答案:

答案 0 :(得分:0)

你的代码对我来说很奇怪。

如果AgendaViewControllerUIViewController,那么应该在主线程上触及它。 因此,我会将您用于检索服务数据的代码分配给与UIViewController相关的代码。

我会修改代码如下。这是一种可能的解决方案。

// spinner could become a strong property int the presenter controller
self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.spinner.center = CGPointMake(160, 240);
self.spinner.hidesWhenStopped = YES;
[self.view addSubview:self.spinner];
[self.spinner startAnimating];

__weak typeof(self) weakSelf = self;

// moved the dispatch_queue into an instance variable or property but do not forget to release
dispatch_async(downloadQueue, ^{

    // call the service here to retrieve serverData

    // do any UI stuff on the main UI thread
    dispatch_async(dispatch_get_main_queue(), ^{

        typeof(self) strongSelf = weakSelf;
        if(strongSelf) {
            AgendaViewController *agenda = [[ AgendaViewController alloc] initWithNibName:nil bundle:nil];
            agenda.serverData = serverData;
            [strongSelf.navigationController pushViewController:agenda animated:YES];
            [strongSelf.spinner stopAnimating];     
        }    
    });

});

答案 1 :(得分:0)

问题必须与您实例化议程 VC的方式有关。如果您使用的是xib个文件,则需要将xib的名称传递给initWithNibName。使用initWithNibName:参数调用nil与调用init相同。它将直接从类定义创建一个对象,但它不会在xib文件上自定义创建任何内容。

我相信,当您取消注释 sleepForTimeInterval:行时,您会认为"它的工作原理是因为它在推动空白议程VC之前有足够的时间来显示微调器。

注意:initWithNibName:使用nil参数(我仍然认为你应该只调用init)的唯一方法是命名xib文件在VC之后。更多信息here

更新

根据对此答案的总结,您的长时间运行过程不在async代码内,而在viewDidLoad:内的AgendaViewController方法中。因此,一种解决方案是:

  1. 完全从async删除action代码,并仅使用init/push的{​​{1}}逻辑替换它。
  2. AgendaViewController UIActivityIndicatorView内添加/启动AgendaViewController
  3. 拨打 mySQL 数据库(实际"长时间运行的流程")。
  4. 收到数据时停止微调器/ activityIndi​​cator
  5. 我不知道您是如何实施 mySQL 调用(web服务/ api)的,但它应该提供viewDidLoad:block方法完成后调用。这是您需要添加逻辑以停止微调器的地方。