我很困惑,一旦我完成它,如何正確處理大中央調度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
,則必須注意不要在清除處理程序運行之前釋放通道。這太刺激了,我不知道這是否是一個錯誤。或者我錯過了什麼?