UIBarButtonItem直到函数返回后才更新标题

时间:2014-03-17 19:17:36

标签: ios objective-c cocoa uibarbuttonitem

我正在创建一个从一个站点加载基于嗅探的数据库的应用程序,所有这些都是通过" onlineSetup"方法

由于这种方法可能会停留一段时间,我想将statusText设置为" Connecting"所以用户知道他必须等待。问题是:' setTitle'在onlineSetup返回的方法之前被忽略,即使在之后调用onlineSetup方法。

- (void)modeSwitchChanged:(id)sender
{
if (self.modeSwitch.isOn)
{
    [self setStatusText:@"Buscando dados: YokaiAnimes" withColor:[UIColor blackColor]];
    if ([self.db onlineSetup]) [self setStatusText:[NSString stringWithFormat:@"Animes encontrados: %d",self.db.animes.count] withColor:[UIColor greenColor]];
    else
    {
        [self.db offlineSetup];
        [self setStatusText:@"Falha: internte desconectada." withColor:[UIColor grayColor]];
        [self.modeSwitch setOn:false animated:true];
    }
}
else
{
    [self.mainTableView setBackgroundColor:[UIColor whiteColor]];
    [self setStatusText:@"Buscando dados: Memória Interna" withColor:[UIColor blackColor]];
    [self.db offlineSetup];
    [self setStatusText:[NSString stringWithFormat:@"Animes encontrados: %d",self.db.animes.count] withColor:[UIColor redColor]];
}
[self.mainTableView reloadData];
}

- (void)setStatusText:(NSString*)t withColor:(UIColor*)c
{
[self.statusLabel setTitle:t];
[self.statusLabel setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:c,NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
}

1 个答案:

答案 0 :(得分:0)

在所有代码完成运行之前,界面中没有任何事情发生。这就是iOS的工作方式。因此,如果您希望接口中的更改现在发生,您需要暂时离开主线程,让runloop完成循环,然后再继续。

- (void)modeSwitchChanged:(id)sender {
    if (self.modeSwitch.isOn) {
        [self setStatusText:@"Buscando dados: YokaiAnimes" withColor:[UIColor blackColor]];
        dispatch_async(dispatch_get_main_queue(), ^{
             // call onlineSetup here
        });
     // ...

确实,如果onlineSetup真的很耗时,你应该在后台线程(而不是dispatch_get_main_queue())上,因为如果你长时间占用主线程,你将受到惩罚即时死亡(好吧,无论如何,你的应用程序)。但当然最终你必须回到主线程来对接口进行任何进一步的更改。这就是GCD如此伟大的原因;它使这种线程切换变得简单而安全。

事实上,如果您正在进行网络连接,那么您肯定应该使用异步网络。执行此操作的能力直接内置于iOS中;如果你故意做同步网络,请立即停止并修复它。最后得到一个回调,你可以在那时返回主线程。