Cocoa 蓝牙同步读取
现在我正在使用IOBluetooth开发一个程序,我需要进行同步读取,也就是说,我调用一个方法,它将给定数量的字节写入端口,然后读取给定数量的字节并返回它们。我目前有一个由NSThreads、NSLocks和NSConditions组成的复杂系统,虽然可以工作,但速度非常慢。另外,在某些调用之后,我需要确保没有额外的数据,因此我通常会刷新缓冲区,但使用IOBluetooth的异步回调是不可能的-有没有想过如何确保无论发生什么情况,在特定点之后接收的所有数据都是在该点之后接收的数据 我真的没有处理过这种类型的同步和多线程,因为到目前为止我所做的所有工作都是使用同步调用,所以我非常感谢您对这件事的任何想法 以下是传入数据的回调(“incomingData”对象是NSMutableData): 下面是一个方法,它在返回数据对象(从另一个线程调用)之前一直等待,直到收到给定数量的字节Cocoa 蓝牙同步读取,cocoa,macos,asynchronous,synchronization,iobluetooth,Cocoa,Macos,Asynchronous,Synchronization,Iobluetooth,现在我正在使用IOBluetooth开发一个程序,我需要进行同步读取,也就是说,我调用一个方法,它将给定数量的字节写入端口,然后读取给定数量的字节并返回它们。我目前有一个由NSThreads、NSLocks和NSConditions组成的复杂系统,虽然可以工作,但速度非常慢。另外,在某些调用之后,我需要确保没有额外的数据,因此我通常会刷新缓冲区,但使用IOBluetooth的异步回调是不可能的-有没有想过如何确保无论发生什么情况,在特定点之后接收的所有数据都是在该点之后接收的数据 我真的没有处理
-(NSData*)waitForBytes:(int)numberOfBytes{
bytesToWaitFor=字节数;
[数据锁];
dataWaitCondition=[[NSCondition alloc]init];
[数据等待条件锁];
[数据锁解锁];
while([incomingData length]
以同步方式进行任何类型的IO/通信都会给您带来麻烦
通过对应用程序逻辑使用简单的状态机,可以避免多线程和锁。无论何时收到数据,状态机都会被触发并处理数据。如果所有数据都存在,您可以在应用程序中执行下一步。如果您愿意,您可以使用同步呼叫进行发送,因为它只会通过蓝牙系统删除数据 事实上,我解决了部分问题,是的,你完全正确,但出现的更大问题是,使用新数据的异步调用速度太慢。该应用程序是实时的,但我们只从IOBluetooth接收大约1-5 Hz的传入数据,这太慢了。知道为什么数据来得这么慢吗?我需要让呼叫尽快进入。RFCOMM模拟串行端口,但必须发送该串行数据的L2CAP数据包。因此,在发送端可能会有一些排队,也许可以使发送更频繁。您还可以使用PacketLogger查看数据的输入速度,以及数据是否在OSX端缓冲。
- (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;
}