2014-09-19 3 views
0

Я хотел бы знать, как я могу достичь следующего в Objective-C,NSThread проснувшись

Я делаю связи с FTDI232R модемом с использованием последовательной связи, поэтому я использую POSIX вызов, чтобы открыть, писать и читать путь модема (dev/tty/nameOfModem). Звонки POSIX - это синхронные вызовы, поэтому, читая, я не хочу блокировать свой основной поток, поэтому я думаю, что нужно читать вызов в отдельном потоке.

Я не хочу, чтобы этот вторичный поток работал непрерывно, но просыпался только тогда, когда есть что читать, и после того, как чтение завершено, он должен спать. Я просмотрел документацию и прочитал о предоставлении источника ввода для NSRunLoop и добавив, что runloop во вторичный поток, но не мог понять, как это сделать.

Заранее благодарю вас за вашу помощь.

ответ

0

У вас обычно есть BOOL, чтобы указать свое состояние запуска, а затем дату для запуска до. При выполнении сокетов-у вещи, я стараюсь сделать что-то вроде:

NSDate *beforeDate = [NSDate dateWithTimeIntervalSinceNow:.1]; 
while (self.isActive && [[NSRunLoop currentRunLoop] runMode: NSRunLoopCommonModes beforeDate:beforeDate]) { 
    beforeDate = [NSDate dateWithTimeIntervalSinceNow:.1]; 
} 

И тогда, когда вы отключиться от модема, вы можете установить IsActive на NO, чтобы спина runloop вниз.

В то время как не точно что вы хотите, документы Apple на threading with NSOperation могут быть интересны для вас.

0

Для этого вам, вероятно, следует использовать GCD dispatch sources. Вот пример кода копируется непосредственно из этой статьи:

dispatch_source_t ProcessContentsOfFile(const char* filename) 
{ 
    // Prepare the file for reading. 
    int fd = open(filename, O_RDONLY); 
    if (fd == -1) 
     return NULL; 
    fcntl(fd, F_SETFL, O_NONBLOCK); // Avoid blocking the read operation 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_source_t readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, 
            fd, 0, queue); 
    if (!readSource) 
    { 
     close(fd); 
     return NULL; 
    } 

    // Install the event handler 
    dispatch_source_set_event_handler(readSource, ^{ 
     size_t estimated = dispatch_source_get_data(readSource) + 1; 
     // Read the data into a text buffer. 
     char* buffer = (char*)malloc(estimated); 
     if (buffer) 
     { 
     ssize_t actual = read(fd, buffer, (estimated)); 
     Boolean done = MyProcessFileData(buffer, actual); // Process the data. 

     // Release the buffer when done. 
     free(buffer); 

     // If there is no more data, cancel the source. 
     if (done) 
      dispatch_source_cancel(readSource); 
     } 
    }); 

    // Install the cancellation handler 
    dispatch_source_set_cancel_handler(readSource, ^{close(fd);}); 

    // Start reading the file. 
    dispatch_resume(readSource); 
    return readSource; 
} 
+0

Спасибо за Ваш ответ и code.I есть вопрос о коде и что кастрированный баран этого кода или блока будет вызываться всякий раз, когда есть данные для чтения в файле ? –

+0

Код не блокируется. Когда есть данные, доступные для чтения в дескрипторе файла, блок обработчика события источника отправки будет отправлен в очередь, указанную при создании источника. В этом примере это одна из глобальных параллельных очередей. Кроме того, дескриптор файла был настроен на неблокирующий режим, поэтому даже вызов 'read()' в блоке обработчика событий не будет блокироваться. Если данных нет, он будет возвращать -1 и устанавливать 'errno' в' EAGAIN' или 'EWOULDBLOCK'. Этого не должно быть, потому что источник не вызвал бы обработчик событий, поэтому он не обрабатывается здесь. –