Возврат в фоновый поток из обратного вызова UIAlertViewDelegate

У меня есть последовательность импорта, которая читает из архива, разархивирует содержащие файлы и создает соответствующие основные объекты данных для каждого. Весь этот процесс происходит в фоновом режиме, и для каждого потока и т. Д. Был создан отдельный контекст, поэтому все работает нормально.

Оказывается, что желательной особенностью этой конкретной последовательности импорта является то, что мы разрешаем любой из входных файлов быть защищенными паролем (их несколько в архиве), поэтому мне нужно проверить, защищен ли файл паролем в этом случае пользователю будет предложено ввести пароль через UIAlertView,

Это где моя проблема начинается.

Я отправляю UIAlertView подскажите основной ветке как надо, назначьте мой импортер object как delegate и ждать ввода пользователя.

Когда пользователь вводит пароль и нажимает OK/Cancel, обратный вызов делегата все еще находится в главном потоке, поэтому я больше не могу манипулировать соответствующим объектом данных ядра без большой работы (т.е. сохранение ссылок на идентификатор управляемого объекта и т. Д., Создание нового контекст и т. д.).

Мой вопрос:

Можно ли вернуться к моей исходной фоновой ветке, где работает процесс импорта? Как бы я пошел по этому поводу?

Спасибо Рог

1 ответ

Решение

Я бы попробовал использовать семафор диспетчеризации. Сохраните его в переменной экземпляра.

@interface MyClass ()
{
    dispatch_semaphore_t dsema;
}
@end

Затем в методе фонового потока:

// this is the background thread where you are processing the archive files
- (void)processArchives
{
    ...
    self.dsema = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle: @"Title"
                                                                ...
                                                           delegate: self
                                                                ...
        ];
        [alertView show];
    });

    dispatch_semaphore_wait(self.dsema, DISPATCH_TIME_FOREVER);
    // --> when you get here, the user has responded to the UIAlertView <--

    dispatch_release(self.dsema);
    ...
}

UIAlertView вызовет этот метод делегата:

// this is running on the main queue, as a method on the alert view delegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // do stuff with alertView
    if (buttonIndex == [alertView firstOtherButtonIndex]) {
        ...
        // when you get the reply that should unblock the background thread, unblock the other thread:
        dispatch_semaphore_signal(self.dsema);
        ...
    }
}
Другие вопросы по тегам