Возврат в фоновый поток из обратного вызова 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);
...
}
}