OutputStream hasSpaceAvailable永远不会成为'true'

时间:2013-11-04 15:34:56

标签: ios objective-c cocoa-touch external-accessory

在iPhone上,使用ios 6.1.3,我正在尝试写入一个没有NSRunLoop的outputStream。我的流简单地通过以下方式初始化:

    session = [[EASession alloc] initWithAccessory:accessory
                                       forProtocol:protocolString];
    if (session)
    {
        NSLog(@"opening the streams for this accessory");
        [[session inputStream] open];
        [[session outputStream] open];
        [session retain];
        streamReady = true;
        receivedAccPkt = true;
    }

然后,代码中的其他地方,当我尝试按如下方式传输数据时:

uint8_t requestData[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
while (![[eas outputStream] hasSpaceAvailable]);
@synchronized(self) {
    len += [[eas outputStream] write:requestData maxLength:8];
}

'hasSpaceAvailable'方法永远不会返回true,因此代码被卡住了。

为了发送数据,是否还有其他的输出流初始化任务?

1 个答案:

答案 0 :(得分:2)

EASession文档指出,您需要通过为流分配一个处理流事件的委托并在运行循环中安排它来配置流。

使用运行循环可以驱动流而不必担心线程。例如,如果通过outputStream属性写入输出流,则很可能是{em>内部输入流(绑定到公共可见输出流),{{1对象获取写入的字节。此内部输入流(不可见)也可能使用与公开提供的输出流EASession相同的运行循环。

不要将内部输入流与公共输入流不匹配!基本上,有两个公共流和两个内部流。每个公共流在内部都有一个关联的链接:输入流具有绑定的输出流,输出流具有绑定的输入流。

可以但是,避免为你的(输出)流使用运行循环:你只需要保证在{em>私有上执行outputStream方法> thread,write:maxLength:未被内部流使用。

只需使用发送即可获取您的私有线程。您可以尝试以下代码:

EASession

注意:如果先前对dispatch_async(dispatch_get_global_queue(0, 0), ^{ [outputStream open]; const char* data = ...; int dataLength = ...; while (dataLength && !isCancelled) { int written = [outputStream write:(const uint8_t*)data maxLength:1]; if (written > 0) { dataLength -= written; data += written; } else if (written < 0 ) { // error occurred break; } } [outputStream close]; }); 的调用返回零并且仍有数据需要写入,则会阻塞该线程。因此,内部流不能使用相同的线程,否则会导致死锁。

当线程被阻塞时,很难取消该块。也许,你应该尝试一种运行循环方法。