версии Xcode: 7.2.1, IOS версии: 9.1+UIAlertController не показывает сразу
Я пытаюсь отобразить предупреждающее сообщение UIAlertController на IPad, который показывает «Загрузка ... Пожалуйста, подождите» сообщение без каких-либо на нем. Я представляю UIAlertController перед началом длительной операции, а затем после продолжительной операции я отклоняю UIAlertController. Однако, что происходит, UIAlertController НЕ появляется сразу. Он только вспыхивает кратковременно ПОСЛЕ завершения более длинной операции, а затем он отклоняется.
Ниже приводится общая структура кода:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
/// Perform long operation here...
/// (Basically, a message is being sent to a server, a long operation happens on
/// the server, and then the server returns a response to the iPad client.)
[alert dismissViewControllerAnimated:YES completion:nil];
}
Я попробовал несколько вариантов, как с помощью dispatch_async так, что предупреждающее сообщение может отображаться одновременно в то время длительной эксплуатации происходит:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/// Perform long operation here...
dispatch_async(dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
});
});
}
Я пробовал использовать UIAlertView (который я знаю, устарел в iOS 8), как в одиночку, так и с отправкой, но это тоже не работает.
Я пробовал обернуть длинный код операции в сообщении performSelector, но безрезультатно.
В прошлом использование UIAlertView с dispatch_queue без проблем работало в этой ситуации.
Любая помощь приветствуется.
Edit:
одна интересная вещь, чтобы отметить: В коде dispatch_async, если добавить USleep (250000) перед вызовом длинного кода операции, около 80% времени, предупредительное сообщение UIAlertController Будет отображаться в правильное время: ПЕРЕД началом длительной операции. Однако это не в 100% случаев и не является устойчивым решением. Вызов спящего с меньшим числом не работает.
Обратите внимание, что для параметра DISPATCH_QUEUE_PRIORITY_DEFAULT, я также пытался: DISPATCH_QUEUE_PRIORITY_HIGH, DISPATCH_QUEUE_PRIORITY_LOW и DISPATCH_QUEUE_PRIORITY_BACKGROUND
И я попробовал следующее тоже:
dispatch_queue_t myQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
/// Perform long operation here...
dispatch_async(dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:nil];
});
});
Вашего вторым вариантом является правильным, вы должны разместить больше коды о вашей длительной эксплуатации. Возможно, что вы блокируете основной поток где-то внутри длинной операции. Это вызовет именно эту проблему. – Sulthan
@Sulthan Да, в длинном коде операции я использую TCP-сокеты для ** отправки ** и ** recv ** данных. Функция ** recv ** socket блокируется до тех пор, пока она не получит свои данные с сервера. – silverness
Вы делаете это в фоновом потоке (во второй версии), так что это не должно быть проблемой. Я думаю, вы каким-то образом также блокируете основной поток. – Sulthan