Подтвердить что ты не робот

В чем основное отличие между NSTimer, NSTask, NSThread и NSRunloop?

В чем разница между NSTimer, NSTask, NSThread и NSRunloop и есть ли руководство по использованию каждого из них?

4b9b3361

Ответ 1

Каждая программа запускается, по крайней мере, в одном потоке. Вы можете думать о каждом потоке как о отдельном процессе выполнения программы, каждый из которых выполняется параллельно другим.

Если у вас есть какой-то пользовательский интерфейс или другой код, который должен прослушивать события (например, сетевые порты), вам нужен цикл выполнения. Каждый NSThread автоматически получает свой собственный цикл запуска, и вам очень редко приходится беспокоиться о них непосредственно. Запуск цикла также отвечает за создание и освобождение пулов автоопределения.

[EDIT: см. комментарии для более подробного обсуждения пулов авторефератов. Самый важный момент, который следует иметь в виду, это то, что новые потоки должны заботиться о создании пула автозапуска. Например, методы, вызываемые с помощью detachNewThreadSelector (см. Ниже), должны иметь следующие строки в качестве их первой и последней строк:

   NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
   [code here]
   [pool release];

То же самое относится к потокам, созданным с использованием других методов.]

В основном потоке, где происходит обработка UI, цикл цикла очень важен, поскольку он поддерживает взаимодействие интерфейса. Вот почему вы никогда не должны запускать код, занимающий много времени в основном потоке: он будет все время тратиться на поток, и цикл выполнения не будет работать достаточно часто, что приведет к блокированному или медленному интерфейсу. Если вам нужно выполнить трудоемкие вычисления или сохранить задание в фоновом режиме, вы должны создать новый поток. Опять же, вам, вероятно, не нужно думать о создании нового цикла цикла. Простой способ выполнения метода в новом потоке:

[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil];

Связь между потоками может быть сложной, и вы должны знать о методах performSelector:onThread:withObject:waitUntilDone: и performSelectorOnMainThread:withObject:waitUntilDone: (Великие советы по отправке NSNotifications по потокам здесь.)

Таймеры также обрабатываются циклами запуска. В отличие от циклов запуска, вы, вероятно, часто используете таймеры непосредственно в своей программе. Самый простой способ создания таймера:

[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];

но иногда вы хотите сами создавать и управлять объектами NSTimer, например, чтобы отменить и повторно использовать таймер.

NSTask используется для запуска другой программы в качестве подпроцесса текущего. Это немного похоже на запуск отдельного потока, но если сбой подпроцесса, ваша основная программа будет работать. Связь между программами также очень отличается от связи между несколькими потоками в одном и том же процессе.

Вы отметили свой вопрос с помощью "iphone", и на iPhone вы никогда не будете использовать NSTasks.

NSOperations используются, когда вам нужно обрабатывать большее количество различных задач, помещая их в очереди и/или обрабатывая их в отдельных потоках (хотя они не должны запускаться в отдельных потоках), Если вашему приложению нужно создать только несколько специализированных потоков, то нет причин использовать класс NSOperation. Но если вы будете регулярно создавать задачи (например, общаться с сервером), которые должны отслеживаться, NSOperation и NSOperationQueue пригодится.

Ответ 2

  • NSTimer - объект таймера, способ вызова селектора на объект в будущем.
  • NSThread - класс потоков. Полагаю, вы знаете, что такое поток.
  • NSTask - это класс процесса, способ запуска другой программы из вашей программы.
  • NSOperation (я добавляю к вопросу) - очень хорошая абстракция для одной задачи. Вы встраиваете свою операцию в этот класс, и вы можете легко выполнить одновременно с помощью класса NSOperationQueue.
  • NSRunLoop является самым трудным для понимания. В некотором роде абстрагирует и адаптирует системный вызов select() unix, управляющий источниками входных сигналов и диспетчеризация событий и таймеров в потоке.

Руководством является Руководство по программированию Apple Threading.

Ответ 3

Другие ответы выполняют довольно хорошую работу по суммированию таймеров, задач и потоков. Я хотел еще немного рассказать о NSRunloop, поскольку, как я думаю, большинство других ответов по-прежнему оставляют некоторую путаницу здесь. Из документации NSRunloop:

Объект ввода процесса NSRunLoop для таких источников, как мышь и клавиатура события из оконной системы, NSPort объектов и объектов NSConnection. Объект NSRunLoop также обрабатывает События NSTimer.

и

В общем, ваше приложение не необходимо либо создать, либо явно управлять объектами NSRunLoop. каждый Объект NSThread, включая основной поток приложений Объект NSRunLoop автоматически создается для этого по мере необходимости. Если вам нужно доступ к текущему циклу выполнения потоков, вы делаете это с помощью метода класса currentRunLoop.

Подумайте о NSRunloop как о главном цикле обработки событий и диспетчеризации для конкретного потока. Он считывает с устройств ввода, обслуживает любые объекты, которые необходимо обслуживать, и отправляет данные соответствующим образом.