Сбой iPhone при представлении контроллера модального представления

StackOverflow https://stackoverflow.com/questions/1412021

Вопрос

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

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    LoadViewController *loader = [[LoadViewController alloc] init];
    [self presentModalViewController: loader animated:NO];
    [loader release];
}

Но когда я делаю это, я получаю "Принятый программой сигнал:"EXC_BAD_ACCESS"." ошибка.

Трассировка стека - это:

0  0x30b43234 in -[UIWindowController transitionViewDidComplete:fromView:toView:]
1  0x3095828e in -[UITransitionView notifyDidCompleteTransition:]
2  0x3091af0d in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]
3  0x3091ad7c in -[UIViewAnimationState animationDidStop:finished:]
4  0x0051e331 in run_animation_callbacks
5  0x0051e109 in CA::timer_callback
6  0x302454a0 in CFRunLoopRunSpecific
7  0x30244628 in CFRunLoopRunInMode
8  0x32044c31 in GSEventRunModal
9  0x32044cf6 in GSEventRun
10 0x309021ee in UIApplicationMain
11 0x00002154 in main at main.m:14

Есть какие-нибудь идеи?Я в полном замешательстве!Загрузочный вид пуст, так что там определенно ничего не происходит, что вызывает ошибку.Это как-то связано с запуском 2 представлений модально в одном цикле событий или что-то в этом роде?

Спасибо,

Майк

Редактировать:Очень странно...Я немного изменил его, чтобы вид загрузки отображался с небольшой задержкой, и это работает нормально!Таким образом, похоже, что это что-то внутри одного и того же цикла событий!

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}
Это было полезно?

Решение

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

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    // Show load
    [self performSelector:@selector(doit) withObject:nil afterDelay:0.1];
}

- (void)doit {
    [self presentModalViewController:loader animated:YES];  
}

Другие советы

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

Прочитав сообщения в этой теме, я попытался создать простой воспроизводимый пример, используя шаблон приложения панели вкладок.Я смог использовать UIImagePickerController для отображения первого модального представления после ответа на нажатие кнопки в "FirstViewController.m".Когда я попытался снова показать UIImagePickerController (после обработки сообщения imagePickerControllerDidCancel), приложение завершило работу с той же ошибкой.

На устройстве просто не было никакой подсказки, что происходит.Однако, когда я запустил код в симуляторе, мне посчастливилось получить это сообщение на консоли:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempting to begin a modal transition from to while a transition is already in progress. Wait for viewDidAppear/viewDidDisappear to know the current transition has completed'

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

Вот полная трассировка стека для полноты картины:

** Call stack at first throw:
(
 0   CoreFoundation                      0x0238c919 __exceptionPreprocess + 185
 1   libobjc.A.dylib                     0x024da5de objc_exception_throw + 47
 2   CoreFoundation                      0x02345078 +[NSException raise:format:arguments:] + 136
 3   Foundation                          0x000ab8cf -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
 4   UIKit                               0x00544317 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 212
 5   UIKit                               0x0035c769 -[UIViewController presentModalViewController:withTransition:] + 2937
 6   TestTempDelete                      0x000021cf -[FirstViewController showImagePicker] + 167
 7   Foundation                          0x0002fcea __NSFireDelayedPerform + 441
 8   CoreFoundation                      0x0236dd43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
 9   CoreFoundation                      0x0236f384 __CFRunLoopDoTimer + 1364
 10  CoreFoundation                      0x022cbd09 __CFRunLoopRun + 1817
 11  CoreFoundation                      0x022cb280 CFRunLoopRunSpecific + 208
 12  CoreFoundation                      0x022cb1a1 CFRunLoopRunInMode + 97
 13  GraphicsServices                    0x02bf12c8 GSEventRunModal + 217
 14  GraphicsServices                    0x02bf138d GSEventRun + 115
 15  UIKit                               0x002beb58 UIApplicationMain + 1160
 16  TestTempDelete                      0x00001eb4 main + 102
 17  TestTempDelete                      0x00001e45 start + 53

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

** Как было сказано ранее, используйте isIgnoringInteractionEvents

//Check if the app is ignoring interatctions, if so, add a delay for 1 sec
if([[UIApplication sharedApplication] isIgnoringInteractionEvents]==TRUE) {
        [currentViewController performSelector:@selector(presentModalViewController:animated:) withObject:screen afterDelay:1];
    } else {
        [currentViewController presentModalViewController:screen animated:YES];
    }

Возможно, если вы получаете это после нажатия кнопки, которая была связана с вашим кодом в Interface Builder, у вас есть два действия, связанные с одной кнопкой (возможно, если у вас было модальное представление, связанное с кнопкой, затем вы продублировали кнопку и связали другое модальное представление).Это попытается отключить их оба, и поэтому с этим сообщением произойдет сбой.

Я столкнулся с таким же исключением

Завершение работы приложения из-за неперехваченного исключения 'NSInternalInconsistencyException', причина:"Попытка начать модальный переход от к, в то время как переход уже осуществляется.Дождитесь появления viewDidAppear / viewDidDisappear, чтобы узнать, что текущий переход завершен '

Как предлагалось ранее, я попытался отложить представление модального перехода, но на самом деле это не помогло.Затем я обнаружил, что у меня есть несколько IBActions, подключенных к событию touchUpInside моей кнопки!!!.В моем случае запустились бы два IBActions:модальное представление средства выбора людей и модальное представление средства выбора изображений.Это объясняет сообщение об ошибке.Проверьте, подключено ли у вас несколько IBActions!

Ваша проблема, скорее всего, в методе, который инициализирует и представляет метод, в котором находится viewDidAppear , или в методе init / viewDidLoad / viewWillAppear LoadViewController.

Установите несколько точек останова и следуйте до тех пор, пока не произойдет сбой...

У меня возникла аналогичная ошибка при нажатии на UIButton чтобы открыть Modal View.Я изменил UIButton's слушатель из UIControlEventAllEvents Для UIControlEventTouchUpInside.По сути, это был запуск модального представления на Touch Down Inside а затем снова на Touch Up Inside.

У меня была такая же проблема из-за несоответствия между именами в

HelpViewController *controller = [[HelpViewController alloc] initWithNibName:@"HelpView" bundle:nil];

и имя фактического файла .xib.

Я думаю, что эта проблема как-то связана с проблемой, с которой я также столкнулся.Это очень легко воспроизвести:

Создайте новый проект XCode "Служебное приложение".В FlipsideViewController.m вы просто вставляете следующий метод:

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear: animated];
  [self showInfo];
}

Если вы сделаете это, запустите приложение, тогда вид с обратной стороны будет активирован сразу же сразу.Как только вы нажмете кнопку "Готово" на обратной стороне экрана, вы вернетесь к главному экрану, который снова запускает viewDidAppear и переходит обратно к обратной стороне экрана- просмотр.Как только отображается вид с обратной стороны, приложение останавливается - нет памяти вызываются средства освобождения - это так же, как если бы вы нажали кнопку "Домой".

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

Я действительно понятия не имею, в чем на самом деле заключается эта проблема...

С наилучшими пожеланиями, Тобиас

Это действительно зависит от того, для чего предназначены процедуры поддержки viewDidAppear делаем.Например, если presentModalViewController:animated: не сохраняет loader авария может быть вызвана UIWindowController пытаясь говорить о loader который с тех пор был выпущен (в конце опубликованной вами процедуры).

У меня была похожая проблема при использовании той же техники, что и у вас, для реализации загрузочного представления.Это привело бы к сбою, когда загрузочный вид был бы отклонен в конце загрузки.В моем случае проблема возникла из-за того, что, как только представление загрузки было отклонено, viewDidAppear был вызван снова и попытался снова представить представление загрузки, что, предположительно, вызвало сбой.Я исправил это, просто проверив, был ли представлен загрузочный вид ранее:

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

    if(needDisplayLoader)
        [self presentModalViewController: loader animated:NO];
}

Затем я установил needDisplayLoader в значение NO, прежде чем отклонить представление Loader

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

Я столкнулся с этой проблемой только сейчас и исправил ее, используя предложение selector: afterDelay выше.Просто чтобы добавить, я скомпилировал (без исправления) под iPhone OS 4.0 beta, и НИКАКОГО СБОЯ!Итак, ошибка в XCode, похоже, была исправлена в следующем поколении.Не то чтобы это принесло кому-то из нас какую-то пользу сегодня, но, чтобы вы все знали, это действительно был ошибка в Xcode и не обязательно что-то, что мы делали неправильно в наших стилях кодирования.

Была точно такая же проблема.Решил это с помощью предложенного выше...

[self performSelector:@selector(doit) withObject:nil afterDelay:0.5];

Пришлось использовать задержку в 0,5 секунды.Возможно, потому, что я выполнял presentModalViewController непосредственно после модального UIPickerViewController.

У меня только что была эта проблема, и оказалось, что моя проблема заключалась в том, что я освободил своего делегата протокола.

Я думаю, причина цикла заключается в том, что новый загружаемый вами контроллер представления по умолчанию имеет метод viewDidAppear, и он имеет

[super viewDidAppear animated];

это означает, что он снова вызовет viewDidAppear вашего основного контроллера представления, например, что он перейдет в цикл

в Viewcontroller, который вы представляете, есть подобный метод, без super viewdidapper:

-(void)viewDidAppear:(BOOL)animated{
    //[super viewDidAppear:animated]; no super

}

EXC_BAD_ACCESS это ошибка памяти.Вероятно, вы пытаетесь использовать объект, который уже был освобожден.Этот ответ дает несколько советов по отладке этих проблем:

Отладка EXC_BAD_ACCESS

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top