“Wait_fences: не вдалося отримати відповідь: 10004003”?


94

Я отримую цю загадкову помилку вперше (і лише вперше), коли моє подання завантажується через такий рядок коду:

- (void)viewWillAppear:(BOOL)animated
{
    [textField becomeFirstResponder];
}

Через це виникає помітна затримка (~ 3 - 4 секунди, навіть на симуляторі), через що у мого додатка виникає відчуття невідповідності. Хтось знає, як це виправити? Я не можу знайти жодної документації на цьому веб-сайті Apple, а також жодних рішень тут чи в Google.

Дивно, але трапляється зворотна ситуація, якщо я вкладаю рядок -viewDidAppear:замість -viewWillAppear:; тобто замість друку помилки відображається лише перший раз, коли клавіатура відображається, і ніколи більше, помилка друкується не вперше, а кожен раз після. Це викликає у мене головний головний біль.

Відповіді:


103

Перевизначте -viewDidAppear:, ні -viewWillAppear, і обов’язково зателефонуйте [super viewDidAppear:]. Не слід виконувати анімацію, коли вас немає на екрані ("з'явиться"). І -viewDidAppear:документи пояснюють, що ви повинні телефонувати, superтому що у них є свої справи.


Це не настільки чуйне, як хотілося б (все одно невелика затримка показує клавіатуру кожного разу), але, схоже, це робить трюк.
Майкл

1
Я знаю відставання, про яке ви говорите. Я бачив це у багатьох додатках. Ви можете спробувати зателефонувати -becomeFirstResponder до (а не після) дзвінка - [super viewDidAppear:], якщо ви цього ще не зробили. Це може не мати впливу, але анімація може початися в тому ж циклі подій, а не в наступному. Я ще не експериментував із цим, щоб підтвердити.
Роб Нейпір,

14
Це не вирішує проблему. Якщо ви видаєте UIAlertSheet у viewDidAppear, після виклику [super viewDidAppear: animated], ви отримуєте одне і те ж повідомлення, кожен раз. якщо, однак, ви викинете його згодом, скажіть у відповідь на невдоволення, не біда. так виконайтеWithSelector - це, мабуть, спосіб виправити, або ви можете проігнорувати повідомлення, в будь-якому випадку це видається помилкою SDK, а не проблемою з вашим кодом.
Біллі Грей,

9
@Billy, викидання UIAlertSheet перед виконанням анімації, швидше за все, призведе до тієї ж проблеми. У будь-якому випадку ви розміщуєте аркуш усередині viewDidAppear, мабуть, занадто рано, і вам, мабуть, слід скористатися perforSelector: afterDelay: для висунення UIAlertSheet до наступного циклу. Це не помилка SDK, хоча деталі тут недостатньо задокументовані. Виконання анімації в -viewWillAppear було помилкою у вихідному коді. У будь-якому випадку не слід ігнорувати повідомлення. Це може призвести до дивних візуальних артефактів (дивне бокове ковзання анімації).
Роб Нейпір,


22

Я швидко отримував подібну помилку:

  1. Відхилення модального виду
  2. Оновлення основного подання
  3. Представлення нового модального виду

Я помітив, що отримую його лише на тренажері, а не на пристрої. Крім того, я потрапляв у нескінченну петлю.

Моїм рішенням було затримати подання нового модального виду. Схоже, що швидке оновлення ієрархії подання спричинило певний стан раси в коді Apple.

Маючи це на увазі, спробуйте наступне:

     - (void)viewDidAppear:(BOOL)animated{

            [super viewDidAppear:animated];
            [textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
  }

Можливо, у вас виникли проблеми з презентацією клавіатури для UITextField, якого ще немає на екрані. Це може спричинити проблеми, подібні до моїх.

Крім того, ви призупиняєте, надаючи ієрархії час на оновлення перед поданням клавіатури, про всяк випадок.

Сподіваюся, це допомагає.


3
Що стосується проблем, які у вас виникали з модальними видами, чи чекали ви, поки модаль закінчить відмову, перш ніж представляти новий модальний? Замість того, щоб чекати довільний проміжок часу і сподіватися, що він завершиться, ви можете це знати, замінивши -viewDidDisappear в modalViewController. Це може передзвонити модальному -parentViewController або може опублікувати повідомлення. Головне зрозуміти, що просити щось звільнити ще не означає, що воно ще немає, і ви не повинні анімувати речі один на одного взагалі. -viewWill / DidDisappear - це, як правило, ваш найкращий спосіб точно знати, коли щось трапляється.
Роб Нейпір,

Першим модальним видом був підбір фотографій, і я обробляю все, що відбувається у методі зворотного виклику вибору фотографій. Ваше право, я мав би розмістити код для запуску наступного модального подання в viewDdiAppear. це краще рішення і, швидше за все, вирішить проблему незалежно від платформи.
Кори Флойд,

12

Переконайтеся, що ви взаємодієте лише з інтерфейсом користувача в основному потоці. Я отримав, 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];
    }
});

9

Спробувавши все, що я міг знайти в Google, і жодне з них не працювало, саме це вирішило проблему для мене. Ключ у тому, що я роблю ці речі у методі делегування willDismissWithButtonIndex. Раніше я робив це в іншому місці.

- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
    [myTextField resignFirstResponder];
    [myTextField removeFromSuperview];  
    [myTextField release];  
}

8

Якщо у вас є наступний рядок у viewDidLoad, це може спричинити це повідомлення. Прокоментуйте наступний рядок.

[[UIApplication sharedApplication] setStatusBarHidden:YES]; //This line should be commented

(Натомість ви можете вимкнути рядок стану з файлу plist програми).


7

Після кількох тестів великим правилом є: "Не виконувати анімацію перед анімованим звільненням або анімаційним шоу.".

Наприклад:

  • не дзвоніть -dismissModalViewControllerAnimated:YESпісля зворотного виклику делегування (зачекайте зникнення подання сповіщення, перш ніж робити це за допомогоюUIAlertView -alertView:willDismissWithButtonIndex:-alertView:didDismissWithButtonIndex: зворотного виклику)
  • не намагайтеся показати клавіатуру ( becomeFirstResponder), поки ваш контролер перегляду не з'явиться на екрані.

Можуть трапитися погані речі.

Сподіваюся, це буде корисним ;-)


Я використовував clickedButtonAtIndex і зробив купу текстових полів, які заповнювались перед тим, як попередження було відхилено. Переключення його на didDismissWithButtonIndex, безумовно, допомогло позбутися цих попереджень! Дякую!
Нітін Алабур,

5

Це спрацювало для мене, щоб клавіатура показала себе негайно, без анімації та затримки.

Нехай 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];

Цікаво. Ви впевнені, що це працює постійно? Мене турбує те, що ви не посилаєтесь view, тому не впевнений, що файл nib завантажений. Якщо textFieldце IBOutlet, то я думаю, що на даний момент це буде нуль.
Роб Нейпір,

5

Ви зробили [textfield becomeFirstResponder];

І після того, як ви отримаєте значення з текстового поля у своєму коді, зробіть [textfield resignFirstResponder];. Це вам допоможе, я думаю.


4

Якщо у вас запущений поточний iPhone Simulator 4.0, це повідомлення про помилку часто з’являється при обертанні екрана (або при анімації після обертання екрана), що супроводжується затримкою анімації на 1-2 секунди.

У цій версії симулятора це помилка, і незабаром її слід виправити.


дякую за інформацію про помилку симулятора iOS4. для того ж проекту wait_fencesповідомлення не з’явилось у симуляторі 3.1
ого

3

Дивіться тут для отримання додаткової інформації: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait_fences-failed-receive-reply-10004003-a.html

Ваша проблема пов'язана.


Дякую за допомогу, але, на жаль, я не можу знайти рішення своєї проблеми на цій сторінці. "Це, здається, відбувається, коли підпрогляд (наприклад, UIAlertView) створюється до його батьківського / суперподання." Це не повинно відбуватися у наведеному вище коді, так?
Майкл

3

замінити viewDidappear, а не viewWillAppear:

-(void) viewDidAppear:(BOOL) animated
{
 [super viewDidAppear:animated];
 [myTextField becomeFirstResponder];
}

3

Я можу імітувати це один на один за допомогою цього коду 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, і мої проблеми були вирішені. Можливо, це стосується й інших випадків?


1

Також з UIAlertView. Для мене це вирішило те, що я подав у відставку, як зазначено нижче, як це було сказано раніше у складських лабораторіях.

- (void)didPresentAlertView:(UIAlertView *)alertView
{
    [txtListingPassword becomeFirstResponder];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [txtListingPassword resignFirstResponder];
}

Інші представники UIAlertViewDelegate не вирішили проблему.


1

Проблема полягає в тому, що в коді Apple є расова умова. Зазвичай це пов’язано з неправильним оновленням інтерфейсу користувача.

З мого досвіду, ви або не викликали супер в viewDidAppear, viewWillAppear тощо. Або ви намагаєтесь відобразити UIAlertView у viewDidLoad або viewWillAppear.

Коли ви додаєте UIAlertView, фреймворк потребує посилання на ваш батьківський подання. Але якщо ви знаходитесь у viewWillAppear або viewDidLoad, подання насправді не відображається ... Вам слід подумати про переміщення коду до viewDidAppear там, де подання готове до використання UIAlertView.


0

Текстове поле міститься в цьому поданні чи в іншому? Ви можете надіслати 'becomeFirstRepsonder' лише на те, що знаходиться безпосередньо в цьому поданні. Якщо він зберігається в якомусь іншому компоненті віджета, ви не повинні встановлювати статус першого відповідача в цьому віджеті, а краще у віджеті, який створюється. Наприклад, якщо ви додаєте текстове поле до подання сповіщень, оскільки шоу відбувається асинхронно, воно може не закінчитися до того часу, як ви зателефонуєте postatiFirstResponder. (В ідеалі у вас буде свій власний клас подання сповіщень і ви визначите текстове поле в ньому, а коли це представлення отримає viewDidAppear, ви встановите текстове поле першим відповідачем на той момент.)


0

Я також отримую повідомлення, wait_fences: failed to receive reply: 10004003а мої viewWill...і viewDid...методи не роблять нічого, крім надсилання повідомлень на super. У моєму випадку це трапляється, коли у мене є UIAlertViewпоказ, GameViewControllerа користувач замість цього натискає круглу кнопку пристрою iPhone, а потім повертається до програми. Це виглядає з моїх рук.


0

Попередження або таблиці дій повинні відображатися в основних потоках ... тому, якщо ви встановлюєте будь-які синхронні підключення та виконуєте цю операцію в іншому потоці та показуєте попередження на основі результатів, отриманих від цієї операції, ви отримаєте це повідомлення про помилку wait_fences: не вдалося отримати відповідь: 10004003. Ви можете зробити щось на зразок ....

[self performSelectotOnMainThread:@selector(handleOutput:) withObject:output waitUntilDone:YES/NO];

і показати сповіщення в методі handleOutput, передаючи рядок вихідної відповіді як параметр.


0

Рішення тут!

У мене була та сама помилка, тепер я отримав рішення, це може вам допомогти.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
  [self performSelector:@selector(YOUR_METHOD) withObject:nil afterDelay:0.1];
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.