Я пытаюсь реализовать параллелизм в objective C
. У меня есть проблема с действиями, которые нужно запускать синхронизированным образом. Проблема здесь в том, что я использую функцию, которая выполняет блок после завершения.Обработка параллелизма и асинхронный ответ
Я хочу подключиться к устройству Bluetooth для выполнения некоторых операций и подключения к следующему устройству.
for (Beacon * beacon in beacons) {
[beacon setDelegate:self];
[beacon connectToBeacon];
}
Но соединение является асинхронным. Маяк вызовет метод делегирования (в этом случае это тот же класс) didConnectSuccess
, когда соединение выполнено успешно.
Мне нужно подождать все мои операции в «beaconDidConnect
» и разблокировать, чтобы завершить работу перед подключением к следующему устройству.
Я сейчас использую комбинацию очереди отправки и отправки семафор, мой семафор является Ивар
dispatch_queue_t myCustomQueue;
myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
for (Beacon * beacon in beacons) {
[beacon setDelegate:self];
dispatch_async(myCustomQueue, ^{
dispatch_semaphore_wait(semaphoreBluetooth, DISPATCH_TIME_FOREVER);
[beacon connectToBeacon];
});
}
В сочетании с
- (void)beaconDidDisconnect:(Beacon *)beacon
{
dispatch_semaphore_signal(semaphoreBluetooth);
}
Без dispatch_async, путем блокирования обратного вызова (beaconDidConnect), ожидание вызывало тупик. Я хотел dispatch_semaphore_wait
в цикле for, а не в блоке отправки, но ожидание вызывает повторный вызов, что вызывает тупик.
Этот способ, кажется, работает, но я нашел его немного уродливым.
Моя другая проблема заключается в том, что в моем методе beaconDidConnect
мне нужно связать asynchronous
звонок и в каждом ожидании предыдущего для завершения.
Все эти вызовы имеют завершающий блок, выполняемый при выполнении вызова. Я мог писать инструкции в более глубоком и глубоком блоке, но я хотел бы избежать этого.
Мне нужен эквивалент концепции «обещание» javascript.
В настоящее время у меня есть что-то с диспетчерской очередью и отправкой семафора, но иногда я имею тупик по неизвестной причине.
Например:
- (void)beaconConnectionDidSucceeded:(Beacon *)beacon
{
dispatch_semaphore_t semaphoreEditing = dispatch_semaphore_create(1);
dispatch_queue_t editingQueue = dispatch_queue_create("com.example.MyCustomQueue.Editing", NULL);
// First writing procedure
dispatch_async(editingQueue, ^{
dispatch_semaphore_wait(semaphoreEditing, DISPATCH_TIME_FOREVER);
[beacon writeSomeCaracteristic:caracteristic withValue:value withCompletion:^(void) {
dispatch_semaphore_signal(semaphoreEditing);
}];
});
// A unknow number of writing sequences
dispatch_async(editingQueue, ^{
dispatch_semaphore_wait(semaphoreEditing, DISPATCH_TIME_FOREVER);
[beacon writeSomeCaracteristic:caracteristic withValue:value withCompletion:^(void) {
dispatch_semaphore_signal(semaphoreEditing);
}];
});
//
// ...
//
dispatch_async(editingQueue, ^{
dispatch_semaphore_wait(semaphoreEditing, DISPATCH_TIME_FOREVER);
[beacon writeSomeCaracteristic:caracteristic withValue:value withCompletion:^(void) {
dispatch_semaphore_signal(semaphoreEditing);
}];
});
// Terminate the edition
dispatch_async(editingQueue, ^{
dispatch_semaphore_wait(semaphoreEditing, DISPATCH_TIME_FOREVER);
[beacon disconnectBeacon];
dispatch_semaphore_signal(semaphoreEditing);
});
}
Я хочу написать ясный код, выполнять мои инструкции в последовательном пути.
Я думал об этом решении, но я думал, что в ObjectiveC есть более идиоматический способ сделать это. Спасибо! – luxcem
Я думаю, что это «идиоматический»;) К сожалению, Objective-C не имеет встроенных функций для выражения асинхронного стиля программирования, такого как ключевое слово «async» или «yield», как на других языках. – CouchDeveloper