Как указать основной поток пользовательского интерфейса, когда фоновая задача завершена? (PerformSelectorInBackground) - PullRequest
2 голосов
/ 07 ноября 2011

Как я могу получить указание на основной поток пользовательского интерфейса в программе IOS приложения iPhone, когда фоновая задача завершена?

Фон

  • Я пытаюсь установить индикатор загрузки в соответствии с концепцией на Как добавить UIActivityIndicator на заставку в приложении для iPhone?
  • собирался в AppDelete использовать "executeSelectorInBackground" для загрузки данных модели
  • поэтому мне нужно, чтобы в RootViewController был какой-то способ сообщить, когда данные закончили загружаться в фоновом режиме, чтобы он мог (а) обновить представление таблицы данными и (б) удалить любой индикатор активности
  • Я предполагаю, что способ сделать что-то здесь заключается в следующем:
    • в делегате приложения didFinishLaunchingWithOptions передает загрузку данных модели в фоновый режим
    • AppDelegate загружает RootViewController и сразу устанавливает индикатор активности
    • как только данные загружаются в фоновом режиме, он каким-то образом должен сообщить об этом обратно RootViewController (причина этого вопроса), что он завершен
    • 2-й вопрос, вероятно, также, когда фоновая задача указывает на завершение, как RootviewController может проверить, что пользовательский интерфейс получил настройку (с индикатором активности и т. Д.), Прежде чем попытаться отключить индикатор активности

Ответы [ 2 ]

3 голосов
/ 07 ноября 2011

Вы можете перезвонить в основную ветку из селектора фона, используя -performSelectorOnMainThread:withObject:waithUntilDone:, например:

- (void)loadModel
{
    // Load the model in the background
    Model *aModel = /* load from some source */;

    [self setModel:aModel];
    [self performSelectorOnMainThread:@selector(finishedLoadingModel) withObject:nil waitUntilDone:YES];
}

- (void)finishedLoadingModel
{
    // Notify your view controller that the model has been loaded
    [[self controller] modelLoaded:[self model]];
}

Обновление : еще более безопасный способ сделать это - проверить -finishedLoadingModel, чтобы убедиться, что вы работаете в главном потоке:

- (void)finishedLoadingModel
{
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:YES];
    }
    // Notify your view controller that the model has been loaded
    [[self controller] modelLoaded:[self model]];
}
1 голос
/ 07 ноября 2011

Как только вы закончите загрузку в фоновом режиме, вызовите следующее из фонового потока:

[self performSelectorOnMainThread:@selector(backgroundLoadingDidFinish:) withObject:nil waitUntilDone:NO];

А затем внедрите -(void)backgroundLoadingDidFinish:(id)sender в свой RootViewController. Если вам нужно, вы можете передать данные обратно вышеуказанным способом (часть withObject:).

...