Только на новом iPad 3: wait_fences: не удалось получить ответ: 10004003

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

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

Я только получаю сообщение об ошибке на новом iPad 3. Я использовал точно такую же программу на оригинальном iPad и iPhone, как 3GS. Все они не получают ошибку wait_fences, и все они вращаются быстрее, чем iPad 3.

Я использую Core Graphics почти исключительно для рисования видов. Я также гарантирую, что они перерисовываются при изменении размера, поэтому я не получаю пиксельные представления. Если я отключаю перерисовку при изменении размера, я не получаю эту ошибку (но получаю растянутые виды). Если я вообще отключаю отрисовку основной графики, я не получаю сообщение об ошибке (но, конечно, я получаю черные виды).

Я использовал Time Profiler и обнаружил, что зависание было в основном при рисовании градиентов: enter image description here

Я изменил код, чтобы заполнить, а не рисовать градиенты, и это облегчает проблему. Я бы сказал, что градиенты являются проблемой, за исключением того, что я делаю эти анимации в других ситуациях (кроме в ответ на вращение), и это работает просто отлично.

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

Я не включил код анимации

Есть идеи, почему это происходит? Тем более, что это происходит только на iPad 3?

Для тех, кто спросит, это код, который выполняет анимацию. Обычно он будет помещен в блок анимации UIView.

- (void) setFramesForFocusView:(CustomControl *)focusView atX:(CGFloat)x showInput:(BOOL)showInput{
    CGSize bSize = self.bounds.size;
    CGRect fRect = focusView.frame;
    fRect.size.width = bSize.width;

    CGRect iRect;
    if (focusView.inputViewIsSystemKeyboard){
        if (_keyboardRect.origin.y < 0 || _keyboardRect.origin.y >= CGRectGetMaxY(self.bounds) || CGRectIsEmpty(_keyboardRect) || CGRectGetMaxY(_keyboardRect) > CGRectGetMaxY(self.bounds)) return;
        iRect = _keyboardRect;
    } else {
        iRect = (focusView.inputUIView && showInput) ? CGRectMake(0, bSize.height / 2, bSize.width, bSize.height / 2) : CGRectZero;
    }

    CGRect iaRect = focusView.inputAccessoryUIView.frame;
    CGFloat availableFieldHeight = iRect.origin.y - iaRect.size.height;

    iRect.size.width = bSize.width;
    iaRect.size.width = bSize.width;

    if (!showInput){
        iRect.origin.y = bSize.height;
    }
    iaRect.origin.y = iRect.origin.y - iaRect.size.height;

    iRect.origin.x = x;
    iaRect.origin.x = x;
    focusView.inputUIView.frame = iRect;
    focusView.inputAccessoryUIView.frame = iaRect;

    if (focusView.expandInput){
        fRect.origin.y = 0;
        fRect.size.height = availableFieldHeight;
    } else {
        if (focusView.labelPlacement != LabelPlacementTop && focusView.labelPlacement != LabelPlacementBottom){
            fRect.size.height = _currentView.storedFrame.size.height + [focusView.label.text sizeWithFont:focusView.label.font].height; 
        }
        fRect.origin.y = availableFieldHeight - fRect.size.height;
    }
    if (fRect.size.height > availableFieldHeight){
        fRect.origin.y = 0;
        fRect.size.height = availableFieldHeight;
    }
    fRect.origin.x = x;
    [focusView setLabelPlacement:LabelPlacementTop toFrame:fRect];
}
 Aaron Hayman07 июн. 2012 г., 21:54
@RobNapier Да, в итоге вы оказались правы. Я трачу столько времени на то, чтобы убедиться, что мой текущий контроллер только анимирует экранные виды, я никогда не думал, что другие контроллеры представления могут создавать свои собственные анимации.
 Swizzlr07 июн. 2012 г., 21:37
Я не могу сказать, насколько это уместно, так как у меня мало опыта с CoreAnimation, но Марко Армент обсуждал специфическую проблему iPad 3 с CA renderInContext, которая связана с прикольным графическим оборудованием. Обсуждение можно найти в его подкасте,Build and Analyze ep 72начиная с 56:20. В результате, я думаю, iPad медленнее. Может быть, что-то можно почерпнуть?
 Swizzlr07 июн. 2012 г., 21:59
Ну, приятно знать! Рад, что вы получили это отсортировано!
 Aaron Hayman07 июн. 2012 г., 21:58
@ThomasCatterall Да, я знаком с «renderInContext». проблема (и я люблю слушать B & A, обычно вживую :)). Фактически, этот эпизод побудил меня купить iPad 3 для тестирования, что оказалось крайне важно. Рад, что мне пришлось заново реализовать много кода, который использовал 'renderInContext'. К счастью, это не было проблемой в этом случае. Я говорю «к счастью» потому что каждый экземпляр, который я должен был заменить, renderInContext требуется много кода для исправления.
 Rob Napier07 июн. 2012 г., 21:14
Тот факт, что это происходит только на iPad 3, в основном предполагает, что это проблема синхронизации, которую iPad 3 достаточно быстр для запуска. В частности, это не говорит о том, что это было правильно на других платформах; только то, что вам повезло на других платформах. Другие ответы, особенно касающиеся несовпадения анимаций начала / конца или анимации в нерабочем состоянии, вероятно, все еще применимы.

Ответы на вопрос(1)

Решение Вопроса

Ну, это было быстро. @RobNapier был прав в том, что это была проблема времени. Я прокомментировал свои анимации, и вау, там было много других видов, оживляющих позади! Даже при том, что я явно анимировал только виды на экране, был другой ViewController, получавший события вращения за моими представлениями без моего ... э-э ... знания? Я имею в виду, я должен знать правильно? Я написал код. Сначала я не осознавал, потому что мой набор просмотров охватывал весь экран. К сожалению, это потребует много переписывания. Я использую пользовательские контроллеры контейнеров и теперь вижу, что мне нужно пересмотреть мою реализацию. Многие вещи бесполезно вращаются / анимируются. Но вау ... это ответило на многие вопросы производительности ....

Update

Поэтому я подумал, что проблема, с которой я столкнулся, связана с дополнительными представлениями, анимированными другими контроллерами представления. Однако, хотя это технически верно, это не так верно, как я думал или как я думал. Я убедился, что никакие другие виды не были анимированы, удалив из окна всю корневую иерархию представлений и заменив ее только контроллером представления, который я хочу повернуть. Это определенно помогло, но не полностью. Действительно, он просто «опустил планку» так что у меня было меньше шансов получить «ожидание»; ошибка. Я все еще обнаружил, что получаю ошибку, хотя в определенных ситуациях.

Я считаю, что проблема, с которой я сталкиваюсь, заключается в том, что я использую UIScrollView. Моя реализация имеет переменное количество подпредставлений, которыми она управляет. Конкретным представлением является моя собственная пользовательская реализация UIPickerView, поэтому, как вы можете себе представить, количество представлений, которыми он управляет, может стать довольно большим. Я обнаружил, что если этих подпредставлений становится слишком много, я начинаю получать «wait_fences» apos; ошибка.

Так что получается, что:If UIScollView is animated, it will animate all of it's subviews, even if those subviews aren't on screen.  Это важно. Я скорее подозреваю, что многие люди, которые борются с этой ошибкой, могут не осознавать этого. Каждое из этих закадровых подпредставлений подталкивает вас все ближе к попаданию на «ожидание». ошибка. Решение в моем случае "простое": я собираюсь преобразовать мой UIScrollView в UITableView. Это будет означать переписывание большого количества кода, но, по крайней мере, я знаю, что закадровые подпредставления будут удалены с экрана и, следовательно, не анимированы.

Я также отметил кое-что еще: Core-Graphic Gradients сильно ударил вас. Я могу анимировать намного больше видов вне экрана, если они не используют градиенты. Конечно, мне нравятся градиенты, и я не хочу от них отказываться (поэтому я переписываю свой PickerView), но это интересно и важно отметить.

Update 2

Закончено переписывание моего UIScrollView в виде tableView, и это, похоже, сработало. У меня нет задержки и нетwait_fences ошибка при повороте экрана.

Update 2

Так что да, намного прощеwait_fences ошибка на iPad 3, чем на любом другом iPad / iPhone. Я просмотрел весь свой код, убедившись, что никогда не анимировал ничего, что не отображается на экране, поэтому эта проблема решена. Я все еще получаюwait_fences ошибка на iPad 3, когда я использую «тяжелый» процедуры рисования. Материал, который я обнаружил, заставляет меня ударить его:

Gradients: gradients really make the CPU work on the retina screen. Transparency: if your view isn't opaque, the CPU works hard to figure out the transparent areas of the view. Transparent Colors: not the same as view transparency. This is layering transparent colors/gradients over the top of each other to gain an 'effect', like gloss, highlights whatever. Textures: I find using textures makes it a little more likely to hit the wait_fences error, but nothing near like what gradients/transparency does.

Ваш ответ на вопрос