Ответ 1
Предполагая, что вы пытаетесь синхронизировать взаимодействие с этим объектом myID
в фоновой очереди, вы хотите, чтобы это было наоборот, блокировка внутри отправленного блока. Сейчас у вас есть:
@synchronized(myID) {
dispatch_async(queue, ^{
// do stuff with myID
});
}
Это синхронизация процесса добавления отправленного блока к вашей очереди, но не синхронизация того, что вы делаете в фоновом режиме. Я подозреваю, что не то, что вы имели в виду.
Вероятно, вы планировали:
dispatch_async(queue, ^{
@synchronized(myID) {
// do stuff with myID
}
});
Он выглядит очень похожим, но приводит к совершенно другому поведению. Теперь синхронизируется работа, отправленная в фоновый режим.
В качестве дополнительного уточнения, если этот отправленный блок, возможно, медленный (и я предполагаю, что это может быть), тогда вы, вероятно, захотите максимально ограничить блок @synchronized
:
dispatch_async(queue, ^{
// do slow stuff in preparation for interacting with `myID`
@synchronized(myID) {
// quickly do stuff with myID
}
// do anything else here
});
Если вы выполняете весь фоновый блок в блоке @synchronized
, вы можете победить всю цель отправки его на задний план, а именно минимизировать влияние на основную очередь. Это последнее изменение смягчает эту проблему.
Как окончательное наблюдение, если у вас есть последовательная очередь (или неглобальная параллельная очередь, в которой вы делаете обновления с барьером), которые часто используются в качестве метода, который полностью исключает необходимость блокировок, если все обновления и запросы для myID
отправляются в эту очередь. См. Устранение кода блокировки в руководстве по программированию Concurrency.