Дождитесь завершения выбора фона для вызова нового метода
Я пытаюсь выполнить сбор данных из интернета под нагрузкой. Чтобы не отставать от пользовательского интерфейса, я выполняю загрузку и анализ HTML с помощью
[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil];
который проверяет, есть ли предупреждение онлайн. Однако для отображения информации в представлении iOS говорит, что мне нужно использовать основной поток. Поэтому я вызываю код дисплея сразу после:
[self performSelectorInBackground:@selector(alertThreadMethod) withObject:nil];
[self loadAlert];
При этом, [self loadAlert];
на самом деле работает перед селектором в фоновом режиме (это быстрее). Из-за этого у него нет информации, которую должен предоставлять селектор в фоновом режиме.
Как я могу гарантировать, что [self loadAlert];
бежит после? Или есть лучший способ сделать это?
2 ответа
Вы можете переместить вызов loadAlert в alertThreadMethod или использовать последовательные очереди Grand Central Dispatch, например,
dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_async(queue, ^{
[self alertThreadMethod];
[self loadAlert];
});
dispatch_release(queue);
Или, если loadAlert обновляет пользовательский интерфейс, так как вы делаете обновления пользовательского интерфейса в основной очереди, вы должны сделать что-то вроде:
dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_async(queue, ^{
[self alertThreadMethod];
dispatch_async(dispatch_get_main_queue(), ^{
[self loadAlert];
});
});
dispatch_release(queue);
Кстати, если вы просто выполняете эту одну задачу в фоновом режиме, а не создаете свою собственную последовательную очередь, вы можете просто использовать одну из существующих фоновых очередей. Вам нужно создать очередь только в том случае, если вам нужен последовательный характер (т. Е. У вас будет много вызовов dispatch_async, и вы не сможете одновременно их запускать). Но в этом простом случае это может быть даже немного более эффективно, минуя создание и освобождение последовательной очереди:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
[self alertThreadMethod];
dispatch_async(dispatch_get_main_queue(), ^{
[self loadAlert];
});
});
В вашем alertThreadMethod после получения информации вызовите метод executeSelectorOnMainThread:withObject:waitUntilDone: и передайте ему селектор в свой метод loadAlert.
-(void)alertThreadMethod
{
// get your information here
performSelectorOnMainThread:@selector(loadAlert) withObject:nil waitUntilDone:NO
}