Каждая программа выполняется как минимум в одном потоке . Вы можете рассматривать каждый поток как отдельный процесс выполнения программы, каждый из которых работает параллельно другим.
Если у вас есть какой-то пользовательский интерфейс или другой код, который должен прослушивать события (например, сетевые порты), вам необходим цикл выполнения . Каждый NSThread автоматически получает свой собственный цикл выполнения, и вам очень редко приходится напрямую им заниматься. Цикл выполнения также отвечает за создание и освобождение пулов автоматического выпуска.
[РЕДАКТИРОВАТЬ: см. Комментарии для более подробного обсуждения пулов autorelease. Важно помнить, что новые потоки должны заботиться о настройке пула автоматического выпуска. Например, методы, которые вызываются с detachNewThreadSelector (см. Ниже), должны иметь следующую первую и последнюю строки:
NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
[code here]
[pool release];
То же самое относится к потокам, порожденным другими методами.]
В главном потоке , где выполняется вся обработка пользовательского интерфейса, цикл выполнения очень важен, поскольку он поддерживает интерфейс реактивным. Вот почему вы никогда не должны запускать код, который занимает много времени в главном потоке: он будет постоянно поглощать поток, и цикл выполнения не сможет запускаться достаточно часто, что приведет к блокировке или медленному интерфейсу. Если вам нужно выполнить трудоемкие вычисления или оставить задачу в фоновом режиме, вам следует создать новый поток. Опять же, вам, вероятно, не нужно думать о создании нового цикла выполнения. Простой способ выполнения метода в новом потоке:
[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil];
Межпотоковое взаимодействие может быть сложным, и вы должны знать методы performSelector:onThread:withObject:waitUntilDone:
и performSelectorOnMainThread:withObject:waitUntilDone:
(Хорошие советы по отправке уведомлений NSN по всем темам здесь .)
Таймеры также обрабатываются циклами выполнения. В отличие от циклов выполнения, вы, вероятно, часто используете таймеры непосредственно в вашей программе. Самый простой способ создания таймера:
[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];
но иногда вы хотите сами создавать объекты NSTimer и управлять ими, например, чтобы иметь возможность отменить и повторно использовать таймер.
NSTask используется для запуска другой программы в качестве подпроцесса текущей. Это немного похоже на запуск отдельного потока, но если произойдет сбой подпроцесса, ваша основная программа продолжит работу. Связь между программами также сильно отличается от связи между несколькими потоками в одном процессе.
Вы отметили свой вопрос как «iphone», и на iPhone вы никогда не будете использовать NSTasks.
NSOperations используются, когда вам нужно обрабатывать большее количество различных задач, помещая их в очереди и / или обрабатывая их в отдельных потоках (хотя они не имеют для запустить в отдельных темах). Если вашему приложению нужно создать всего несколько специализированных потоков, то нет смысла использовать класс NSOperation. Но если вы будете регулярно генерировать задачи (например, связь с сервером), которые необходимо отслеживать, NSOperation и NSOperationQueue пригодятся.