wait_fences: не удалось получить ответ: 10004003 (снова)

Еще один крик о помощи по поводу этого предупреждения.

Прежде всего, я рассмотрел все вопросы здесь, в другом месте, и ни один из них не подходит для моей ситуации. Он не имеет ничего общего с блоками оповещений и отставкой в ​​качестве первого респондента, а также не выполняет анимацию перед отображением представлений. Моя проблема возникает при создании пользовательской клавиатуры на основе UIView.

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

Здесь слишком много кода для публикации, поэтому я просто дам краткое описание того, что происходит:

ViewController "Calc" создает экземпляр пользовательского "DataView" на основе UIView в методе loadView VC, а затем добавляет его в качестве дополнительного представления VC.

"DataView" создает пользовательский UITextField на основе "TextFieldKPD" в методе init DataView

"TextField" создает экземпляр пользовательской клавиатуры "KeyPad" на основе UIView в методе init TextField и назначает эту KeyPad входному представлению TextField.

"KeyPad" создает 13 UIButton-ов типа UIButtonTypeCustom, считывает и присваивает "нажатые" и "не нажатые" изображения для каждой кнопки, а также задает действия для кнопок. Затем он добавляет каждую кнопку как подпредставление себя. (Контролируя, когда в жизненном цикле UIView KeyPad происходит эта конструкция, можно настроить предупреждение wait_fences: см. Ниже.)

"Calc" ViewController - это тот, который изначально представлен пользователю. Я отследил предупреждение wait_fences, возникающее после завершения метода калькулятора viewDidLayoutSubViews и до вызова его метода viewDidAppear. Обратите внимание, что клавиатура не отображается при отображении Calc.

Кажется, я могу контролировать действие предупреждения wait_fences, изменяя конструкцию клавиатуры:

  • Если UIButtons создаются и добавляются как подпредставления в методе init KeyPad, тогда я получу предупреждение, один раз и только один раз.

  • Если вместо этого кнопки создаются и добавляются в метод layoutSubViews KeyPad, то предупреждение не появляется. (Но клавиатура эффективно не создается, пока я не нажму на TextField - тем не менее, предупреждения wait_fences тоже нет)

В loadView Calc нет анимации или чего-либо еще. Это экземпляр и назначить весь путь вниз.

Таким образом, есть какие-либо комментарии к этой версии wait_fences?

РЕДАКТИРОВАТЬ 1, 30 января - теперь с еще большим замешательством!

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

-(void)loadImages
{
    UIImage* image;

    for(int i=0; i<16; i++) {
        image = [UIImage imageNamed:@"StupidFileNameThatDoesNotExist"];
    }
}

Если я выполню [self loadImages] в методе init KeyPad затем появляется предупреждение. Но этот код ничего не делает, так как файл не существует. Я считаю, что если счетчик цикла достаточно мал, чтобы предупреждение исчезло, но я не определил нижний предел.

Если я заменю фактическую загрузку изображения с

[UIImage imageWithContentsOfFile:@"StupidFileNameThatDoesNotExist"]

и по-прежнему вызывать метод во время KeyPad init, тогда я, кажется, не получаю предупреждение. Одно из очевидных различий между этими двумя способами загрузки изображения заключается в том, что imageNamed кэширует изображение внутри.

Поэтому я склоняюсь к ответу Джорджа, что это внутренняя ошибка Apple.

Редактировать 2, 1 февраля - Джим, но не так, как мы его знаем

Так что я убедил себя, что именно кеширование в классе UIImage, очевидно, стало причиной проблемы. Что с этим делать? Ну напиши свой кеш изображений конечно!!

Поэтому я начал подключаться, вырывать тот код, который пытался загрузить недопустимые изображения, и получил точку, где я сгенерировал нужные мне имена файлов и передал их моему контроллеру кеша. Таким образом, чтобы убедиться, что все начинает сближаться, в контроллере кеша я генерировал сообщение NSLog для каждой попытки кешировать изображение - не более того - просто регистрировать имя файла.

И угадайте, что - я снова получаю глупое предупреждение. За то, что не делал никакой реальной работы вообще.

Я могу только заключить, что есть какое-то внутреннее состояние гонки iOS, которое я запускаю, когда добавляю дополнительный код в метод init KeyPad, И что я ничего не могу сделать, чтобы смягчить это. Все, что я могу сделать, это надеяться, что это предупреждение будет добрым.

Редактировать 3, акт Гамлета 1 сцена 4: что-то гнилое в штате Дания

Сохраняя тот же код, что и в Edit 2, я закомментировал оператор NSLog. И предупреждение ушло. Я положил его обратно, и появляется предупреждение.

Итак, код у меня есть:

-(void)loadImages
{
    // Iterate over button definitions and cache the required images
    for(int i=0; i<numKeys; i++) {

        if (![imageCache imageExistsForTag:keyTags[i]]) {
            [imageCache addImageFile:[NSString stringWithFormat:@"%s_NP.png",keyNames[i]] forTag:keyTags[i]];
        }

        if (![imageCache imageExistsForTag:keyTags[i]+pressedOffset]) {
            [imageCache addImageFile:[NSString stringWithFormat:@"%s_P.png",keyNames[i]] forTag:keyTags[i]+pressedOffset];
        }

    }

}

А также:

-(void)addImageFile:(NSString*)imageFile forTag:(int)tag
{
    NSLog(@"Adding tag:%d for file %@", tag, imageFile);
}

С этим оператором NSLog, контролирующим появление предупреждения.

Изменить 4 февраля 2 - Добро пожаловать в Храм Судьбы

Принимая комментарии Аллена близко к сердцу, я перестроил свою клавиатуру как XIB и загрузил ее, вместо того, чтобы вручную пытаться создать представление. Конечно, это ничего не исправило. Я надеялся, что загрузка Nib произойдет за пределами того, что когда-либо вызывает проблему.

У меня такое чувство, что я сталкиваюсь с условиями гонки в loadView of Calc и некоторыми внутренними операциями с iOS. Если я выполняю слишком много работы внутри loadView, я пересекаю черту и отключаю предупреждение wait_fences. И что клавиатура является симптомом, а не основной причиной. То есть это могла быть любая активность, просто клавиатура была последней вещью, которую я делал до того, как появилось предупреждение. Я просто хотел бы, чтобы я действительно знал, каковы были ограничения, которые я фактически пересекал и не спотыкался в темноте.

5 ответов

Решение

Я сталкивался с этой проблемой несколько раз и пытался найти решение. Самое близкое, что я получил, было то, что, по словам инженера Apple, это проблема, вызванная внутренне, и сторонние разработчики не должны беспокоиться об этом. Насколько я знаю, это не должно приводить к сбою вашего приложения или возникновению каких-либо проблем, кроме действительно раздражающей ошибки в отладчике, которая, кажется, сводит всех разработчиков с ума!

Извините, что я не могу помочь.

Насколько я могу судить о вашем описании кода, проблема, кажется, возникает, когда подпредставление (например, UIAlertView) создается до его родительского / суперпредставления. Что-то делать с цепочкой респондента.

Попробуйте переместить коды просмотра, чтобы решить проблему, или вставьте соответствующие детали.

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

? Мне немного неясно, какая у вас иерархия view/viewcontroller...

У вас есть ViewController "Calc", который создает "DataView" для его "основного" представления. "DataView" создает textField "TextFieldKPD" как собственное представление. Затем TextFieldKPD создает подпредставление "KeyPad" UIView, которое само создает для себя 13 подпредставлений UIButton.

Итак, ваши взгляды имеют 4 уровня глубины?

Apple заявляет, что ViewController должен обрабатывать целые скрины представлений (я думаю, это немного изменилось, теперь, когда мы можем создавать контейнерные представления, но цель их утверждения остается). Убедитесь, что события кнопок клавиатуры и события текстового поля обрабатываются вашим viewController.

Конечно, вам лучше создать все эти представления в viewController или в главном представлении, чтобы ваша иерархия была более плоской?

Извиняюсь, если я неправильно понял вашу иерархию.

Кстати, стоит попробовать полностью удалить текстовое поле и посмотреть, сможете ли вы по-прежнему получить ошибку.

По моим сведениям. Это предупреждение появляется, когда мы вызываем UIAlertView и в то же время выполняем некоторые операции над UIView. Чтобы решить эту проблему, нам не нужно выполнять операции на UIView в то время. Для этого мы можем сделать одну из двух вещей: 1. Мы можем вызвать UIAlertView с некоторой задержкой, чтобы завершить операцию над UIView. 2. Или мы можем выполнить операции над UIView в методе - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; Так что UIAlertView нет в нашем UIView в то время, когда некоторые операции выполняются в UIVIew.

Надеюсь, это поможет вам.

Другие вопросы по тегам