У меня есть два метода, которые запускаются в последовательной очереди. Каждый метод возвращает копию некоторого класса. Я пытаюсь достичь решения безопасности потока, а также для обеспечения целостности данных.Последовательная очередь GCD и состояние гонки
, например:
-(Users *) getAllUsers
{
__block copiedUsers;
dispatch_sync(_backgroundQueue, ^{
copiedUsers = [self.users copy]; // return copy object to calling thread.
});
return copiedUsers;
}
-(Orders *) getAllOrders
{
__block copiedOrders;
dispatch_sync(_backgroundQueue, ^{
copiedOrders = [self.Orders copy]; // return copy object to calling thread.
});
return copiedOrders;
}
В дополнение к этим двум методам, у меня есть класс, который работник добавлять/удалять пользователей и заказы, все сделано через последовательный очереди backgroundQueue
.
Если в главном потоке я вызываю getAllUsers
, а затем getAllOrders
сразу после другого, моя целостность данных небезопасна, потому что между двумя вызовами рабочий класс мог бы изменить модель.
Мой вопрос: как я могу сделать вызывающему приятный интерфейс, который позволяет нескольким методам работать атомарно?
Я отредактировал ваш ответ для более легкого обсуждения. Код внутри 'block_q' ставит очередь' task' в 'backgroundQueue', а затем уведомляет основной поток. Вы получите сигнал обновления перед обновлением 'orders' и' users'. Я думаю, что ваш код будет работать правильно, если у вас есть 'dispatch_semaphore_t' в' block_q' и дождитесь завершения 'runBlockAndGetNeededDataSafely'. – sahara108
Спасибо за редактирование, я его одобрил. Какой сигнал обновления вы имеете в виду? И зачем мне нужно dispatch_semaphore_t? – kernix
Сигнал обновления - 'refreshViewWithUsers'. Поскольку он будет выполнять 'refreshViewWithUsers' независимо от того, что закончилось' runBlockAndGetNeededDataSafely' или нет – sahara108