簡體   English   中英

如果[nsInputStream close]被另一個線程調用,是否應該返回[nsInputStream read:…]?

[英]Should [nsInputStream read:…] return if [nsInputStream close] is called by another thread?

在我看來,如果流被另一個線程關閉,而與套接字連接的另一端無關,則任何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)卻一無所獲)。

每次關閉流時,如何可靠地強制讀取彈出?

另外:

我在帶有5.1 iPad模擬器的ML上使用XCODE 4.4.1。

如果我僅關閉inputStream而沒有釋放或設置為nil,那么也會發生此問題。

經過大量調查,我在SO上遇到了另一個線程,該線程提示了答案:由於本地設備正在斷開連接,因此不會有任何通過read方法傳遞的來自連接(來自遠程端點)的事件。 這個想法是,由於本地設備負責斷開連接,因此它將知道它不應該進入讀取方法(不會讀取任何內容)。 這有點出乎意料,因為當接收器線程已經在read方法中時,用戶可能會斷開連接。 但是... iOS的設計顯然不依賴於接收器線程,而是依賴於運行循環中的事件(這是另一個問題,但我不想在這里討論)。 具體來說,給定運行循環中的事件說有可用數據,則您可以輸入read方法。 因此,您永遠不會輸入read並掛起等待第一個字節。 這與我過去在Windows平台上完成的套接字編程完全不同。 但是到目前為止,我所做的所有實驗都表明這是問題所在。 我有一個現在可以運行的解決方案,該解決方案依賴於工作線程中來自運行循環的流中的事件,因此網絡流量不會干擾GUI(main)線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM