我正在创建一个从一个站点加载基于嗅探的数据库的应用程序,所有这些都是通过" 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];
}
答案 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中;如果你故意做同步网络,请立即停止并修复它。最后得到一个回调,你可以在那时返回主线程。