2012-03-03 71 views
3

我很困惑,一旦我完成它,如何正確處理大中央調度I/O通道。以下(簡化的)實施例使得與消息上的一些私人調度隊列崩潰:BUG IN CLIENT OF LIBDISPATCH: Over-resume of an object正確處理大中央調度I/O通道

- (void)beginReading { 
    dispatch_io_t channel; 
    channel = dispatch_io_create_with_path(DISPATCH_IO_RANDOM, 
              "/Path/To/Some/File", 
              O_RDONLY, 
              0 /*mode*/, 
              someQueue, 
              ^(int errorCode) { 
               // Cleanup handler; executed once channel is closed. 
               // (Or fails to open.) 
              }); 
    // Schedule the read operation 
    dispatch_io_read(channel, 0, SIZE_MAX, someQueue, ^(bool done, dispatch_data_t data, int errorCode) { 
     NSError *error = (errorCode!=0) ? [NSError errorWithDomain:NSPOSIXErrorDomain code:errorCode userInfo:nil] : nil; 
     [self didReadChunk:data isEOF:done error:error]; 
    }); 

    // No more read operations to come, so we can safely close the channel. 
    // (Or can we?) 
    dispatch_io_close(channel, 0); 

    // We don't need a reference to the channel anymore 
    dispatch_release(channel); 
} 

我猜測,日程表dispatch_io_close()一些異步操作以關閉通道,並且直到該操作已完成執行,您不能在頻道上致電dispatch_release(),否則將會發生不良事情。但是這將是相當令人驚訝的:其他GCD異步功能,如dispatch_async(),沒有這個限制。此外,dispatch_io_close()調用似乎並不是絕對必要的,因爲libdispatch似乎通過在通道上最後一次調用dispatch_release()來關閉文件。

由此看來,如果您撥打dispatch_io_close,則必須注意不要在清除處理程序運行之前釋放通道。這太刺激了,我不知道這是否是一個錯誤。或者我錯過了什麼?

回答

4

事實證明這是一個錯誤(雷達#10246694)。進一步的實驗似乎表明它隻影響基於路徑的調度信道,即用dispatch_io_create_with_path()創建的信道,而不是dispatch_io_create()