IOBluetooth Синхронное чтение - PullRequest
4 голосов
/ 26 февраля 2011

Сейчас я работаю над программой, использующей IOBluetooth, и мне нужно синхронное чтение, т. Е. Я вызываю метод, он записывает в порт заданное число байтов, затем читает заданное число и возвращает их. В настоящее время у меня есть сложная система NSThreads, NSLocks и NSConditions, которая хотя и работает, но очень медленная. Кроме того, после определенных вызовов мне нужно убедиться, что нет никаких дополнительных данных, поэтому я обычно очищаю буфер, но с асинхронным обратным вызовом IOBluetooth это невозможно - любые мысли о том, как убедиться, что, несмотря ни на что, все данные, полученные после конкретная точка - это данные, полученные после этой точки?

Я действительно вообще не имел дело с синхронизацией и многопоточностью этого типа, поскольку вся работа, которую я проделал до сих пор, использует синхронные вызовы, поэтому я был бы признателен за любые мысли по этому вопросу.

Вот обратный вызов для входящих данных (объект входящего_данных - NSMutableData):

- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength {
    [dataLock lock];
    NSData *data = [NSData dataWithBytes:dataPointer length:dataLength];
    [incomingData appendData:data];

    if (dataWaitCondition && [incomingData length] >= bytesToWaitFor) {
        [dataWaitCondition signal];
    }

    [dataLock unlock];
    [delegate bluetoothDataReceived];
}

А вот метод, который ожидает получения заданного числа байтов, прежде чем вернуть объект данных (он вызывается из альтернативного потока).

- (NSData *)waitForBytes:(int)numberOfBytes {

    bytesToWaitFor = numberOfBytes;
    [dataLock lock];
    dataWaitCondition = [[NSCondition alloc] init];
    [dataWaitCondition lock];
    [dataLock unlock];
    while ([incomingData length] < numberOfBytes) {
        [dataWaitCondition wait];
    }
    [dataLock lock];
    NSData *data = [incomingData copy];
    [dataWaitCondition unlock];
    dataWaitCondition = NULL;
    [dataLock unlock];

    return data;
}

1 Ответ

0 голосов
/ 22 сентября 2011

Синхронное выполнение любых операций ввода-вывода / связи приведет к неприятностям.

Вы можете избежать многопоточности и блокировок, используя простой конечный автомат для вашей логики приложения. При получении данных конечный автомат запускается и может обрабатывать данные. Если все данные есть, вы можете сделать следующий шаг в вашем приложении. Вы можете использовать синхронные вызовы для отправки, если хотите, так как это просто отбросит данные с помощью системы Bluetooth.

...