Отвечая на ваши вопросы в обратном порядке:
2
. У тебя две проблемы. Документация для -[NSRunLoop run]
гласит:
Если нет входных источников или таймеров
привязанный к циклу выполнения, этот метод
выходит немедленно; в противном случае он работает
приемник в
NSDefaultRunLoopMode
многократно
вызывая runMode:beforeDate:
. В других
словами, этот метод эффективно начинается
бесконечный цикл, который обрабатывает данные
из входных источников цикла выполнения и
таймеры.
Так что, используя собственный цикл выполнения вашего потока, вероятно, нет входных источников, определенных для цикла выполнения, поэтому он возвращается немедленно. Если это так, ваш цикл выполнения зацикливается бесконечно, а остальная часть кода после этой точки никогда не выполняется.
Чтобы все работало правильно, ваш цикл выполнения должен сначала иметь несколько входных источников, а затем должен периодически запускаться для проверки событий. Обратите внимание, что вы не хотите использовать [NSRunLoop run]
, так как вы никогда не получите контроль. Вместо этого я бы рекомендовал установить цикл непосредственно перед return YES
, который непрерывно запускает цикл выполнения, пока поток не будет отменен или пока вы не закончите потоковую передачу данных. Это позволит циклу выполнения обрабатывать данные по мере их поступления. Примерно так:
while (!done) {
[myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
[NSRunLoop runUntilDate:]
обрабатывает события до указанной даты, а затем возвращает управление вашей программе, чтобы вы могли делать все, что захотите.
1
. Это работает, потому что цикл запуска вашего основного потока запускается периодически, поэтому события обрабатываются. Однако, если ваш основной поток заблокирован, ваши данные перестанут поступать. Это может быть особенно плохо, если основной поток ожидает данные из вашего второго потока. Кроме того, NSRunLoop не является потокобезопасным:
Предупреждение: класс NSRunLoop
как правило, не считается
потокобезопасен и его методы должны
вызываться только в контексте
текущая тема. Вы никогда не должны
попытаться вызвать методы
NSRunLoop объект работает в
другой поток, как это может сделать
вызвать неожиданные результаты.
(из документации NSRunLoop.)
Руководство по программированию потоков от Apple имеет раздел под названием Run Loop Management , который объясняет все это в некоторой степени. Это не самый ясный документ, который я когда-либо читал, но если вы работаете с циклами выполнения, это хорошее место для начала.