РЕДАКТИРОВАТЬ: stevex абсолютно прав, что ваш первый приоритет должен найти способ сделать все это асинхронным.В противном случае ответ ниже должен достичь того, что вы хотите, в то же время доверив этапы синхронизации ОС для оптимального энергопотребления.
Возможно, вы хотите использовать NSConditionLock
для блокировки того, что вызывает assetForUrl:...
сразу послевызов, а затем ваши обратные вызовы разблокировать его.
Блокировка условия - это блокировка с условием.Итак, вы говорите: «Я хочу блокировку, когда ее состояние равно X», и ваш поток блокируется, пока она не окажется в этом состоянии.Затем у вас есть блокировка, пока вы не разблокируете ее, и вы можете указать, в каком состоянии она будет находиться сразу после разблокировки.
Условия задаются с помощью NSIntegers;
Таким образом, есть аспекткоммуникации встроены в замок.
Так, например:
NSConditionLock *conditionLock; // somewhere; an instance variable
#define kYourClassInitialCondition 0
#define kYourClassWaitingCondition 1
// etc
...
[conditionLock lockWhenCondition:kYourClassInitialCondition];
[whomever assetForUrl:whatever
resultBlock:^(args here)
{
... do relevant immediate work here ...
[conditionLock lockWhenCondition:kYourClassWaitingCondition];
[conditionLock unlockWithCondition:kYourClassFinishedCondition];
}
failureBlock:^(args here)
{
... as above, same semantics when done ...
}
];
[conditionLock unlockWithCondition:kYourClassWaitingCondition];
[conditionLock lockWhenCondition:kYourClassFinishedCondition];
[conditionLock unlockWithCondition:kYourClassInitialCondition];
Итак, логика в вызывающем потоке такова:
- получить блокировку в начальном состоянии
- выдать запрос на получение URL-адреса
- снять блокировку в состоянии ожидания
- получить блокировку в состоянии готовности
- снять блокировку в исходном состоянии
И логика для блоков результата:
- получить блокировку в состоянии ожидания
- снять блокировку в готовом состоянии
Результирующие блоки будут блокироваться, пока вызывающий поток не переведет блокировку условия в состояние ожидания.Таким образом, нет проблем с секвенированием, если обратные вызовы являются немедленными.
После установления условия ожидания вызывающий поток будет блокироваться, пока блокировка условия не будет снята в завершенном состоянии.Поэтому следует дождаться завершения результирующего блока, если он еще не завершен.
Это, конечно, предполагает, что ваши результирующие блоки отправляются вызываемым абонентом через GCD, или если вызываемый inline вызывается изотдельная тема.Первое, вероятно, безопасное предположение.