Есть ли способ заставить Core Animation запускать поток?

Core Animation использует фоновый поток для выполнения своей работы. Теперь проблема в следующем: у меня в основном потоке выполняется тяжелый расчет. Core Animation немедленно зависает до тех пор, пока этот расчет не будет выполнен. А затем он продолжает заканчивать анимацию. Я помню, как читал в документе, что CA имеет низкий приоритет во времени обработки, а это означает, что все, что хочет сделать основной поток, является приоритетным и будет выполнено с большей вероятностью, чем любая модная анимация одновременно.

Я хочу заставить Core Animation планировать свой фоновый поток в соответствии с основным потоком при любых обстоятельствах. Или, в качестве альтернативы, отдельный поток, который будет выполнять тяжелые вычисления вне основного потока. Я уже пробовал это, но CA все еще зависает, пока это не будет сделано. Я ожидаю, что планировщик быстро переключит время обработки между CA и этим расчетом.

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


person Community    schedule 23.10.2009    source источник


Ответы (3)


Не выполняйте тяжелые вычисления в основном потоке, потому что они заблокируют пользовательский интерфейс и ухудшат взаимодействие с пользователем. Запустите их в фоновом потоке.

Тем не менее, iPhone - одноядерная система, поэтому, если вычисления привязаны к ЦП в одном потоке, производительность каждого другого потока может практически остановиться. Если можете, попробуйте разбить вычисление на более мелкие элементы и запустить их как NSOperations в NSOperationQueue. Если вы убедитесь, что сегменты вычислений не настолько малы, что накладные расходы на создание NSOperation для них станут слишком большими, это может предоставить средства для небольшого регулирования вычислений, чтобы ваши анимации не замедлялись.

Базовая анимация имеет тенденцию выполнять ряд вычислений заранее, прежде чем анимация может быть запущена, поэтому они могут замедляться из-за вашего тяжелого вычислительного потока. Вы также можете начать свои тяжелые вычисления в методе -animationDidStart: delegate для вашей CAAnimation, заставляя вычисление запускаться только во время анимации. Я считаю, что для продвижения анимации требуется меньше вычислений, чем для ее начала, поэтому она может лучше сосуществовать с вашими тяжелыми вычислениями.

person Brad Larson    schedule 23.10.2009
comment
Спасибо. Может ли NSOperations делать таймауты? Мой расчет уже разбит на части. Каждый из них расписан с задержкой 0,05 секунды. Так что на самом деле между ними есть свободное время. Однако, когда CA вначале должен выполнить предварительный расчет, ваша идея ожидания -animationDidStart - это goog. Я попробовал, просто отложив вызов на начало первого блока вычислений на 1 секунду. CA начинает анимацию, затем возникают тяжелые вычисления, и CA зависает. Это не помогает. Провожу расчеты в новой ветке. - person ; 23.10.2009
comment
Дело в том, что после расчета каждого блока данных в пользовательском интерфейсе происходит обновление. Эти обновления происходят быстро и плавно, как и ожидалось. Было бы просто идеально, если бы был способ спланировать все это таким образом, чтобы CA делил с этим процессорное время ... собираюсь взглянуть на эти вещи NSOperationQueue, хотя они не звучат так, как будто они будут обеспечивать тайм-ауты вроде отложенные вызовы performSelector делают (?) - person ; 23.10.2009
comment
NSOperationQueue создает потоки для ваших NSOperations по мере необходимости. Он достаточно умен в том, чтобы управлять тем, какие задачи и когда выполняются, но я не знаю, имеет ли он такой же уровень осведомленности на уровне системы на iPhone, что и на Snow Leopard (где он накладывается поверх GCD). Он также поддерживает зависимости между задачами, которые вы можете здесь использовать в своих интересах. - person Brad Larson; 23.10.2009
comment
звучит отлично. вы уже использовали его на iphone? и как он будет взаимодействовать с основной анимацией? возможно, мне придется избавиться от CA здесь и делать все анимации вручную, чтобы я мог заставить его сбалансированно распределять время процессора ... - person ; 24.10.2009
comment
Даже если бы вам пришлось реализовать свой собственный код анимации вручную (что заняло бы у вас очень много времени), вы столкнетесь с той же проблемой. Если ваши тяжелые вычисления отнимают так много процессорного времени, что вызывают заикание Core Animation, почему вы думаете, что ваша ручная анимация также не будет иметь проблем? Я бы рекомендовал провести некоторое время с Shark and Instruments, чтобы попытаться сначала поработать над тяжелым расчетом. - person Brad Larson; 24.10.2009

Вы можете использовать [CATransaction flush] для сброса основной анимации, если вы не позволяете циклу выполнения идти своим чередом

person monkeydom    schedule 02.05.2011
comment
Хотя, похоже, это работает только на iOS 4.0 и новее. До этого он не заставлял перерисовывать должным образом, но и не доставлял проблем. - person monkeydom; 25.05.2011
comment
Я знаю, что это устарело, но не могли бы вы подробнее рассказать, как [CATransaction flush] помогает с проблемой потоковой передачи? - person Warpling; 25.02.2015

Я не уверен, но вы можете попытаться вызвать [NSThread setThreadPriority:1.0], если ваш центр сертификации работает в другом потоке.

person Morion    schedule 23.10.2009
comment
имеет значение, если я вызову CA в другом потоке? насколько мне известно, CA поддерживает свой собственный процесс и поток для такого рода вещей (или, по крайней мере, свой собственный поток с очень низким приоритетом) - person ; 23.10.2009