В чем разница между performSelectorOnMainThread и dispatch async в основной очереди?
у меня возникли проблемы с изменением представления внутри потока. Я попытался добавить подвида, но это заняло около 6 или более секунд, чтобы отобразить. Я, наконец, получил его работу, но я не знаю, как именно. Поэтому мне было интересно, почему это сработало и в чем разница между следующими методами:
//this worked -added the view instantly
dispatch_async(dispatch_get_main_queue(), ^{
//some UI methods ej
[view addSubview: otherView];
}
//this took around 6 or more seconds to display
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView
waitUntilDone:NO];
//Also didnt work: NSNotification methods - took also around 6 seconds to display
//the observer was in the viewController I wanted to modify
//paired to a method to add a subview.
[[NSNotificationCenter defaultCenter] postNotificationName:
@"notification-identifier" object:object];
для справки это было вызвано внутри этого обработчика завершения класса ACAccountStore.
accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
//my methods were here
}
}
Edit: когда я говорю, что это не сработало, я имел в виду, что это заняло около 6 секунды для отображения вида, который я добавил.
3 ответов:
по умолчанию
-performSelectorOnMainThread:withObject:waitUntilDone:только планирует запуск селектора в режиме цикла выполнения по умолчанию. Если цикл выполнения находится в другом режиме (например, в режиме отслеживания), он не будет выполняться до тех пор, пока цикл выполнения не переключится обратно в режим по умолчанию. Вы можете обойти это с вариантом-performSelectorOnMainThread:withObject:waitUntilDone:modes:(передавая все режимы, в которых вы хотите его запустить).С другой стороны,
dispatch_async(dispatch_get_main_queue(), ^{ ... })запускает блок, как только основной цикл выполнения возвращает поток управления обратно в цикл событий. Он не заботится о режимах. Так что если вы также не хотите заботиться о режимах,dispatch_async()может быть, лучший способ пойти.
скорее всего, потому что
performSelectorOnMainThread:withObject:waitUntilDone:помещает сообщение в очередь с общими режимами цикла выполнения. Согласно от Apple!--5-->Руководство По Программированию Параллелизма, основная очередь будет чередовать поставленные в очередь задачи с другими событиями из цикла запуска приложения. Таким образом, если есть другие события, подлежащие обработке в очереди событий, блоки в очереди отправки могут быть запущены первыми, даже если они были отправлены позже.в этой статье является превосходным объяснением
performSelectorOnMainThreadиdispatch_async, который также отвечает на вопрос выше.
вы пробовали
PerformSelectorOnMainThreadСwaitUntilDone=YESнапример:
код:
[viewController performSelectorOnMainThread:@selector(methodThatAddsSubview:) withObject:otherView waitUntilDone:YES];Я думаю, что это может решить проблему, почему
PerformSelectorOnMainThreadзанимает так много времени, чтобы ответить.
Comments