如果[nsInputStream close]被另一个线程调用,那么[nsInputStream read:...]会返回吗?

时间:2012-08-29 08:30:54

标签: ios nsinputstream

在我看来,如果流被另一个线程关闭而不管套接字连接的另一端是什么,那么任何NSInputStream对象都应弹出其read:方法。但在某些情况下,这似乎并非如此。似乎除非另一方在连接之前首先发送一次至少一次,否则read:方法将不响应流关闭。

打开连接的代码:

    // Open the socket...
    CFStreamCreatePairWithSocketToHost(NULL, Host, Port, &readStream, &writeStream);

    // Create NSStream objects for our use...
    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;

    // take ownership of the NSStream objects...
    [inputStream retain];
    [outputStream retain];

    // open the streams....
    [inputStream open];
    [outputStream open];

关闭连接的代码:

    // Close the streams...
    [inputStream close];
    [outputStream close];

    // Release ownership...
    [outputStream release];
    [inputStream release];

    // clear reference values...
    outputStream = nil;
    inputStream = nil;

在接收线程中:

-(uint8_t) GetByte
{
    uint8_t c;
    int N = [inputStream read:&c maxLength:1];
    if ( N < 1 )
        @throw [[TcpClientException alloc] init];
    return c;
}

当我从主线程关闭流时,接收线程仍然在read方法中。最终它超时并崩溃。即使是崩溃也不会导致抛出任何类型的对象(我试图将代码包围起来以捕获任何东西(id)并且什么都没有)。

每次关闭流时,如何可靠地强制读取弹出?

此外:

我在ML和5.1 iPad模拟器上使用XCODE 4.4.1。

如果我只关闭inputStream并且不释放或设置为nil,那么也会出现问题。

1 个答案:

答案 0 :(得分:0)

经过大量调查后,我在SO处遇到了另一个线程,暗示答案是,由于本地设备正在断开连接,因此通过read方法传递的连接(来自远程端点)不会发生任何事件。我们的想法是,由于本地设备负责断开连接,因此它会知道它不应该进入读取方法(没有任何东西可以读取)。这有点意外,因为当接收器线程已经在读取方法中时,用户可能正在断开连接。但是...... iOS的设计显然不是依赖于接收器线程,而是运行循环中的事件(这是另一个问题,但我不想进入这里)。具体来说,如果运行循环中的事件表明有可用数据,则输入read方法。因此,您永远不会输入读取和挂起等待第一个字节。这与我过去在Windows平台上完成的套接字编程非常不同。但到目前为止我所做的所有试验都表明这是问题所在。我现在有一个解决方案,它依赖于来自工作线程中的运行循环的流中的事件,以便网络流量不会干扰GUI(主)线程。