NSRunLoops в какао? - PullRequest
       38

NSRunLoops в какао?

2 голосов
/ 22 сентября 2010

Допустим, у меня есть 2 потока, один из которых является основным, а другой - вторичным. Основной поток используется чаще всего, но иногда (редко) я хочу, чтобы дополнительный поток выполнял некоторую работу на основе вызовов из основного потока. Большую часть времени вторичный поток должен спать. Теперь, после некоторых поисков, я понимаю, что для этого нужно использовать runLoops. Поэтому я попытался прочитать документы Apple (http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW5)

но мне это кажется очень сложным, и мне там тяжело. Есть ли элегантный и простой способ добиться того, что я описал? Какие-нибудь похожие примеры кода runLoop, которые я могу запустить и поиграть?

Спасибо

Ответы [ 3 ]

4 голосов
/ 23 сентября 2010

Каждый поток имеет цикл выполнения.

Каждый цикл выполнения имеет список вещей, которые необходимо сделать. Эти вещи называются «запланированными» в цикле выполнения, хотя не все они запланированы на определенную дату и время:

  • Таймеры.
  • Источники не являются. Обычно они ждут, чтобы что-то постучало в порт ядра Mach или в дескриптор файла.

Когда цикл выполнения работает, он обычно не работает, то есть поток спит, не потребляя циклов ЦП. (Если вы попробуете его, вы обнаружите, что процесс застрял в mach_msg_trap. Это системный вызов «ожидайте чего-то».) Ядро пробуждает поток (который, таким образом, возвращается из mach_msg_trap) когда что-то происходит, о чем нужно позаботиться в цикле выполнения потока.

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

Однако NSOperation почти наверняка является лучшим решением, поскольку оно разработано для случая, который вы описали: Дискретные единицы работы, которые необходимо выполнять последовательно, до N (которое вы выбираете и составляет не менее 1) за один раз.

Обратите внимание, что NSOperationQueue повторно использует потоки, поэтому он не обязательно создает новый поток для каждой операции. На самом деле, не делать это - часть дела: он лениво создает потоки и использует все, что у него уже есть, но ничего не делает.

4 голосов
/ 22 сентября 2010

Это звучит так, как будто NSOperation / NSOperationQueue был создан для. Если у вас есть только случайные «единицы работы», почему бы не сделать их операцией, а затем отслеживать их выполнение и соответственно обновлять свой пользовательский интерфейс?

2 голосов
/ 22 сентября 2010

Мэтт Галлахер (Matt Gallagher) имеет хорошую статью в блоге, сравнивающую подход вторичной цепочки с другими способами выполнения фоновой работы.

http://cocoawithlove.com/2010/09/overhead-of-spawning-threads.html

В вашем случае вам не нужносвязано с затратами на создание потоков.Но примеры кода Мэтта могут дать некоторое представление об управлении циклом выполнения вторичного потока.

Все это говорит о том, что я бы следовал совету Джошуа и просто использовал NSOperationQueue и NSOperation для выполнения фоновой работы.Если работа может быть инкапсулирована в NSInvocation, вы можете использовать NSInvocationOperation и избежать подкласса NSOperation.

...