Опрос по сравнению с планированием цикла выполнения
Потенциальная проблема с потоковой обработкой блокирует. Потоку, пишущему в или читающему из потока, возможно, придется ожидать неопределенно, пока нет (соответственно) пространство на потоке для помещения байтов или байтов на потоке, который может быть считан. В действительности поток во власти потока, и это может записать проблему приложению. Блокирование может особенно быть проблемой с потоками сокета, потому что они зависят от ответов от удаленного узла.
С потоками Какао у Вас есть два способа обработать потоковые события:
Планирование цикла выполнения. Вы планируете потоковый объект на цикл выполнения так, чтобы делегат получил сообщения, сообщив о связанных с потоком событиях только, когда блокирование вряд ли будет иметь место. Для операций чтения и операций записи, подходящего
NSStreamEvent
константыNSStreamHasBytesAvailable
иNSStreamHasSpaceAvailable
.Опрос. В замкнутом цикле, поврежденном только в конце потока или на ошибку, Вы продолжаете спрашивать потоковый объект, если это имеет (для потоков чтения) байты, доступные в чтение или (для потоков записи) пространство, доступное для записи. Подходящие методы
hasBytesAvailable
(NSInputStream) иhasSpaceAvailable
(NSOutputStream).
Планирование цикла выполнения почти всегда предпочтительно по опросу, и именно поэтому примеры кода в Чтении От Входных Потоков и Записи В Потоки вывода исключительно показывают использование выполненных циклов. С опросом Ваша программа заблокирована в жестком цикле, ожидающем потоковых событий, которые могли бы или не могли бы быть неизбежными. С планированием цикла выполнения Ваша программа может уйти и сделать другие вещи, зная, что это будет уведомлено, когда будет потоковое событие для обработки. Кроме того, выполненные циклы спасают Вас от необходимости управлять состоянием и более эффективны, чем опрос. Опрос также интенсивен CPU; существуют другие вещи, которые можно делать со временем обработки.
Однако могут быть ситуации, где опрос является жизнеспособным вариантом. Например, при портировании устаревшего кода Вы могли бы принять решение использовать опрос, потому что это лучше подходит для модели потоков в устаревшем коде. Перечисление 1 иллюстрирует метод, пишущий данные в опрос использования потока вывода.
Перечисление 1 , Пишущее в опрос использования потока вывода
- (void)createNewFile { |
oStream = [[NSOutputStream alloc] initToMemory]; |
[oStream open]; |
uint8_t *readBytes = (uint8_t *)[data mutableBytes]; |
uint8_t buf[1024]; |
int len = 1024; |
while (1) { |
if (len == 0) break; |
if ( [oStream hasSpaceAvailable] ) { |
(void)strncpy(buf, readBytes, len); |
readBytes += len; |
if ([oStream write:(const uint8_t *)buf maxLength:len] == -1) { |
[self handleError:[oStream streamError]]; |
break; |
} |
[bytesWritten setIntValue:[bytesWritten intValue]+len]; |
len = (([data length] - [bytesWritten intValue] >= 1024) ? 1024 : |
[data length] - [bytesWritten intValue]); |
} |
} |
NSData *newData = [oStream propertyForKey: |
NSStreamDataWrittenToMemoryStreamKey]; |
if (!newData) { |
NSLog(@"No data written to memory!"); |
} else { |
[self processData:newData]; |
} |
[oStream close]; |
[oStream release]; |
oStream = nil; |
} |
Нужно указать, что ни опрос, ни подходы планирования цикла выполнения не являются воздухонепроницаемой обороноспособностью против блокирования. Если NSInputStream hasBytesAvailable
метод или NSOutputStream hasSpaceAvailable
возвраты метода NO
, это означает в обоих случаях, что поток определенно не имеет никаких доступных байтов или пространства. Однако, если любой из этих возвратов методов YES
, это может означать, что существуют доступные байты или пространство или что единственный способ узнать состоит в том, чтобы делать попытку чтения или операции записи (который мог привести к мгновенному блоку). NSStreamEventHasBytesAvailable
и NSStreamEventHasSpaceAvailable
потоковые события имеют идентичную семантику.