как обновить элементы управления пользовательского интерфейса в приложении какао из фонового потока
Простой: Не.
Как прервать/ отменить processStart в то время как цикл из управления пользовательского интерфейса?
За пределами processStart
, установите переменную флага.Внутри processStart
проверьте этот флаг и выйдите из цикла, если он установлен.
Не пытайтесь «убить» поток из другого потока.Это всегда плохая идея. Сообщите потоку, что пришло время остановиться, установив флаг, и попросите поток проверить этот флаг и остановиться в соответствующее время.
Мне также нужно показатьзначение счетчика в основном пользовательском интерфейсе, который я предполагаю делать с executeSelectorOnMainThread и передачей аргумента.Просто хочу знать, есть ли другой способ сделать это?
Да.
Когда мое приложение запускалось, в Activity Monitor показывается 1 поток, но когда я запускалprocessStart () в фоновом потоке создает два новых потока, которые составляют 3 потока до тех пор, пока цикл не будет завершен. После завершения цикла я вижу 2 потока.Итак, я понимаю, что 2 потока были созданы, когда я вызвал executeSelectorInBackground, но как насчет третьего потока, откуда он был создан?
Профилируйте ваше приложение с помощью инструментов или Shark и смотрите.Вероятно, это поток сердцебиения для индикатора прогресса.
Что, если число потоков увеличивается при каждом вызове селектора. Как контролировать это или моя реализация плоха для таких требований?
Каждое сообщение performSelectorInBackground:withObject:
запускает поток.Если количество потоков не уменьшается, это потому, что ваш метод потока не завершился.Если число потоков слишком велико, это (вероятно) потому, что вы запустили слишком много потоков.
Существует гораздо лучший способ сделать это.
Во-первых, общее правило вКакао никогда не спит .Думайте об этом как о специальном какао с ультра-кофеином.Для всего, о чем вы могли бы спать в другой среде, почти всегда есть лучший, обычно более простой способ в Какао.
Имея это в виду, посмотрите на processStart
.Все, что он делает, это делает что-то каждую секунду.Как лучше всего это сделать?
Какао имеет класс для этой конкретной цели: NSTimer.Создайте таймер, который отправляет вам сообщение с желаемым интервалом, и отвечайте на это сообщение, обновляя индикатор выполнения, то есть ваш метод обратного вызова таймера должен быть просто телом цикла из processStart
, без цикла.
Кстати, 100 обновлений в секунду - это перебор.Прежде всего, пользователю все равно, что вы продвинулись на 1/5 от значения пикселя с момента последнего обновления панели.Во-вторых, экран обновляется только около 60 раз в секунду , поэтому обновление всего видимого быстрее, чем это бессмысленно.
- (void)dealloc {
//Never called while debugging ????
[super dealloc];
}
Предполагается, что вы добавили делегата приложенияиз-за этого перо MainMenu объект приложения владеет им, но он этого не знает, потому что знает только о делегате приложения в качестве своего делегата, который не принадлежит.(И даже если бы это были отношения владения, это были бы только два владельца, из которых приложение выпустило бы одно, что не помогло бы.)
Однако время жизни делегата приложения на самом деле неиметь значение.Его назначение в качестве делегата приложения означает, что оно должно длиться примерно столько же, сколько и приложение, но когда приложение уходит, процесс завершается, что означает, что делегат также будет освобожден, как часть восстановленияпространство памяти процесса.Вот почему dealloc
не вызывается - все пространство процесса исчезает сразу, вместо того, чтобы объекты освобождались по одному за раз.
Так что, в принципе, да, делегат приложения не был явно очищенэто немного хитроумно.На практике не помещайте никакие временные файлы очистки в dealloc
(используйте вместо applicationWillTerminate:
), и все будет в порядке.
Я делаючтобы обойти эту проблему, поместите всю мою реальную работу в один или несколько других объектов, которыми владеет делегат приложения. Делегат приложения создает эти другие контроллеры в applicationWillFinishLaunching:
и выпускает их в applicationWillTerminate:
, поэтому эти объекты действительно получают dealloc
сообщения. Проблема решена.