"wait_fences: не удалось получить ответ: 10004003"?
Я получаю эту загадочную ошибку в первый раз (и только в первый раз) мое представление загружается из-за следующей строки кода:
- (void)viewWillAppear:(BOOL)animated
{
[textField becomeFirstResponder];
}
Из-за этого происходит заметная (~3 - 4 секунды, даже на симуляторе) задержка, из-за которой мое приложение перестает отвечать на запросы. Кто-нибудь знает, как это исправить? Я не могу найти какую-либо документацию по этому вопросу на сайте Apple или какие-либо решения здесь или в Google.
Странно, если я поставлю строку в -viewDidAppear:
вместо -viewWillAppear:
; то есть, вместо того, чтобы печатать ошибку только при первом показе клавиатуры и больше никогда, ошибка печатается не в первый раз, а каждый раз после. Это вызывает у меня сильную головную боль.
18 ответов
Override -viewDidAppear:
не -viewWillAppear
и обязательно позвоните [super viewDidAppear:]
, Вы не должны выполнять анимацию, когда вы не на экране ("появится"). И -viewDidAppear:
Документы объясняют, что вы должны позвонить super
потому что у них есть свои дела.
Я получил похожую ошибку, когда быстро:
- Отклонение модального вида
- Обновление основного вида
- Представление нового модального представления
Я заметил, что получаю только в симуляторе, а не на устройстве. Кроме того, я попал в бесконечный цикл.
Мое решение состояло в том, чтобы отложить представление нового модального представления. Похоже, что быстрое обновление иерархии представлений привело к некоторой гонке в коде Apple.
Имея это в виду, попробуйте это:
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
}
У вас могут быть проблемы с представлением клавиатуры для UITextField, которого еще нет на экране. Это может вызвать проблемы, похожие на мою.
Кроме того, вы приостанавливаете предоставление времени иерархии для обновления, прежде чем представить клавиатуру, на всякий случай.
Надеюсь это поможет.
Убедитесь, что вы взаимодействуете только с пользовательским интерфейсом в основном потоке. я получил wait_fences: failed to receive reply: 10004003
пока я сидел там и ждал, пока UIAlertView покажет около 5 секунд, потому что соответствующий код был выполнен в фоновом потоке. Вы можете убедиться, поместив свой код в блок и отправив его в основной поток:
dispatch_async(dispatch_get_main_queue(), ^{
if (!success) {
// Inform user that import failed
UIAlertView * importFailedAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ErrorTitle5", @"Import failed")
message:NSLocalizedString(@"Error5", @"Something went wrong")
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[importFailedAlert show];
}
});
Перепробовав все, что я смог найти в Google, и ничего из этого не заработало, вот что решило проблему для меня. Ключ в том, что я делаю это в методе делегата willDismissWithButtonIndex. Прежде чем я делал это в другом месте.
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
[myTextField resignFirstResponder];
[myTextField removeFromSuperview];
[myTextField release];
}
Если у вас есть следующая строка в viewDidLoad, это может вызвать это сообщение. Прокомментируйте следующую строку.
[[UIApplication sharedApplication] setStatusBarHidden:YES]; //This line should be commented
(Вместо этого вы можете отключить строку состояния в файле plist приложения).
После нескольких тестов основным правилом является: "Не выполняйте анимацию до увольнения или анимационного шоу".
Например:
- не звони
-dismissModalViewControllerAnimated:YES
после обратного вызова делегацииUIAlertView -alertView:
will
DismissWithButtonIndex:
(дождитесь исчезновения из окна предупреждения, прежде чем делать это, используя-alertView:
did
DismissWithButtonIndex:
Перезвоните) - не пытайтесь показать клавиатуру (
becomeFirstResponder
), прежде чем ваш контроллер просмотра на экране.
Могут случиться плохие вещи.
Надеюсь, это будет полезно;-)
Ты сделал [textfield becomeFirstResponder];
И после того, как вы получите значение из текстового поля в вашем коде, выполните [textfield resignFirstResponder];
, Это поможет вам, я думаю.
Это сработало для меня, чтобы заставить клавиатуру показывать себя немедленно, без анимации или задержки.
Позволять textField
быть переменной экземпляра MyViewController
(подкласс UIViewController
).
Вызов [textField becomeFirstResponder]
в initWithNibName:bundle:
(для подкласса UIViewController
) или же initWithStyle:
(для подкласса UITableViewController
), не в viewDidLoad
, Например:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[textField becomeFirstResponder];
}
return self;
}
Или вызвать его сразу после инициализации, но перед нажатием UIViewController
, Например:
MyViewController *viewController = [[MyViewController alloc] init];
[viewController.textField becomeFirstResponder];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
Если вы используете текущий iPhone Simulator 4.0, это сообщение об ошибке часто появляется при повороте экрана (или при анимации после поворота экрана), сопровождающемся 1-2-секундным лагом анимации.
Это ошибка в этой версии симулятора и должна быть исправлена в ближайшее время.
Смотрите здесь для получения дополнительной информации: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait_fences-failed-receive-reply-10004003-a.html
Ваша проблема связана.
Переопределение viewDidappear
не viewWillAppear
:
-(void) viewDidAppear:(BOOL) animated
{
[super viewDidAppear:animated];
[myTextField becomeFirstResponder];
}
Я могу смоделировать это один на один с помощью этого кода UIAlertView.
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(@"defineTitle",@"defineTitle")
message:NSLocalizedString(@"defineBody", @"defineBody")
delegate:self
cancelButtonTitle:NSLocalizedString(@"Ok", @"Ok")
otherButtonTitles:nil];
[alert show];
Если NSLocalizedString не определены в файле Localizable.strings, поиск текстов займет много времени, поэтому появится предупреждение и будет показано "wait_fences: не удалось получить ответ: 10004003".
Я только добавил тексты в файлы Localizable.strings, и мои проблемы были решены. Может быть, это касается и других случаев?
Также с UIAlertView. То, что решило это для меня, имело отставку как ниже, как упоминалось ранее.
- (void)didPresentAlertView:(UIAlertView *)alertView
{
[txtListingPassword becomeFirstResponder];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[txtListingPassword resignFirstResponder];
}
Другие делегаты UIAlertViewDelegate не устранили проблему.
Проблема в том, что в коде Apple есть условие гонки. Обычно это связано с неправильными обновлениями пользовательского интерфейса.
По моему опыту, вы либо не вызывали super в viewDidAppear, viewWillAppear и т. Д. Или вы пытаетесь отобразить UIAlertView в viewDidLoad или viewWillAppear.
Когда вы добавляете UIAlertView, платформе нужна ссылка на ваше родительское представление. Но если вы находитесь в viewWillAppear или viewDidLoad, представление фактически не отображается... Вы должны рассмотреть возможность перемещения кода в viewDidAppear, где представление готово для использования UIAlertView.
Решение здесь!
У меня была та же ошибка, теперь у меня есть решение, это может вам помочь.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
[self performSelector:@selector(YOUR_METHOD) withObject:nil afterDelay:0.1];
}
Я тоже получаю сообщение wait_fences: failed to receive reply: 10004003
и мой viewWill...
а также viewDid...
методы ничего не делают, но отправляют сообщения super
, В моем случае это происходит, когда у меня есть UIAlertView
показывая в моем GameViewController
вместо этого пользователь нажимает круглую кнопку устройства iPhone и затем возвращается в приложение. Это выглядит из моих рук.
Содержится ли текстовое поле в этом представлении или в чем-то еще? Вы можете только отправить функцию “стали для первого раза” в то, что содержится непосредственно в этом представлении. Если он хранится в каком-либо другом компоненте виджета, вы не должны устанавливать статус первого респондента в этом виджете, а скорее в виджете, который создается. Например, если вы добавляете текстовое поле в представление предупреждений, поскольку показ происходит асинхронно, он может не появиться к тому времени, когда вы вызываете становление становления FirstResponder. (В идеале у вас должен быть свой собственный класс представления предупреждений, и вы определяете текстовое поле внутри него, и когда это представление получает viewDidAppear, вы должны установить текстовое поле в качестве первого респондента в этой точке.)
Предупреждения или таблицы действий должны отображаться в основных потоках... поэтому, если вы выполняете какие-либо синхронные подключения и выполняете эту операцию в другом потоке и показывает предупреждения на основе выходных данных, полученных из этой операции, вы получите это сообщение об ошибке wait_fences: не удалось получить ответ: 10004003 . Вы можете сделать что-то вроде....
[self performSelectotOnMainThread:@selector(handleOutput:) withObject:output waitUntilDone:YES/NO];
и показывать оповещения в методе handleOutput, передавая строку выходного ответа в качестве параметра.