Сбой iPhone при представлении модального контроллера
Я пытаюсь отобразить модальное представление прямо после того, как другое представление было представлено модально (второе представляет собой представление загрузки, которое появляется).
- (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-х видов в одном цикле событий или что-то в этом роде?
Спасибо,
Mike
Изменить: Очень странно... Я немного изменил его, чтобы изображение загрузки отображалось после небольшой задержки, и это отлично работает! Таким образом, это похоже на то, что внутри одного цикла событий!
- (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];
}
Ответы
Ответ 1
Я немного изменил его, чтобы изображение загрузки отображалось после небольшой задержки, и это работает отлично! Таким образом, это похоже на то, что внутри одного цикла событий!
- (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];
}
Ответ 2
Я считаю, что я воспроизвел ту же ошибку в iOS 4. В моем приложении авария происходила последовательно, когда пыталась показать второе модальное представление сразу после показа первого модального представления. Я несколько часов боролся с сумасшедшим.
Прочитав сообщения в этом потоке, я попытался создать простой воспроизводимый пример, используя шаблон приложения "Панель вкладок". Я смог использовать UIImagePickerController для отображения первого модального представления после ответа на кнопку щелчка в "FirstViewController.m". Когда я снова попытался показать UIImagePickerController (после обработки сообщения imagePickerControllerDidCancel), приложение разбилось с той же ошибкой.
На устройстве не было никакого понятия, что происходит. Однако, когда я запускал код на Simulator, мне посчастливилось получить это сообщение на консоли:
*** 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
Надеюсь, что это поможет.
Ответ 3
** Как было сказано ранее, используйте 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];
}
Ответ 4
Возможно, если вы получили это после нажатия кнопки, которая была связана с вашим кодом в Interface Builder, у вас есть два действия, связанные с одной кнопкой (возможно, если у вас есть модальное представление, связанное с кнопкой, то дублировал кнопку и связал другой вид модальности). Это попытается отключить их обоих и, следовательно, с этим сообщением не удастся.
Ответ 5
Я столкнулся с тем же исключением
Завершение приложения из-за неотображенного исключения "NSInternalInconsistencyException", причина: "Попытка начать модальный переход с того момента, пока переход уже выполняется. Подождите, пока viewDidAppear/viewDidDisappear узнает, что текущий переход завершен.
Как было предложено ранее, я попытался отложить передачу модального перехода, но это действительно не помогло. Затем я обнаружил, что у меня было несколько IBActions, связанных с моей кнопкой TouchUpInside event!!!. В моем случае начнутся два IBActions: представить сборщика людей по-разному и представить сборщик изображений по тексту. Это объясняет сообщение об ошибке. Проверьте, есть ли у вас несколько IBActions!
Ответ 6
Ваша проблема наиболее вероятна в методе, который inits и представляет метод, в котором находится viewDidAppear, или в методе инициализации /viewDidLoad/viewWillAppear LoadViewController.
Установите некоторые точки останова и следуйте до сбоя...
Ответ 7
Я думаю, что эта проблема имеет какое-то отношение к проблеме, с которой я столкнулся.
Это очень легко воспроизвести:
Создать новый проект XCode "Утилита". В FlipsideViewController.m
вы просто вставляете следующий метод:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear: animated];
[self showInfo];
}
Если вы сделаете это, запустите приложение, тогда обратное отображение будет активировано вправо
далеко. Как только вы нажмете кнопку "Готово" на обратном пути, вы вернетесь
к Mainview, который снова запускает viewDidAppear и идет прямо назад к flipside-
Посмотреть. Как только отображается обратный просмотр, приложение останавливается - нет памяти
вызывающие дезактиваторы называются - это похоже на то, что вы нажали кнопку "home-button".
Когда я использовал некоторые дополнительные свойства в этих представлениях, я также получил исключение,
поэтому я разделил код на минимальную сумму...
У меня действительно нет подсказки, какова эта проблема на самом деле...
С уважением,
Tobias
Ответ 8
У меня была аналогичная ошибка при нажатии на UIButton
, чтобы открыть Modal View
. Я изменил прослушиватель UIButton's
с UIControlEventAllEvents
на UIControlEventTouchUpInside
. В основном, он запускал Modal View на Touch Down Inside
, а затем снова на Touch Up Inside
.
Ответ 9
У меня была та же проблема из-за несоответствия между именами в
HelpViewController *controller = [[HelpViewController alloc] initWithNibName:@"HelpView" bundle:nil];
и имя фактического файла .xib.
Ответ 10
Это действительно зависит от того, что делают подпрограммы поддержки для viewDidAppear
. Например, если presentModalViewController:animated:
не сохраняет loader
, авария может быть вызвана тем, что UIWindowController
пытается говорить о loader
, который с тех пор был выпущен (в конце процедуры, которую вы опубликовали).
Ответ 11
У меня была аналогичная проблема, используя ту же технику, что и вы, чтобы реализовать загрузку. Он сработает, когда в конце загрузки снимок будет снят.
В моем случае проблема возникла из-за того, что, как только окно загрузки было отклонено, viewDidAppear снова был вызван и попытался снова представить загрузку, что предположительно вызвало сбой.
Я исправил это просто, проверив, было ли представление загрузки ранее:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(needDisplayLoader)
[self presentModalViewController: loader animated:NO];
}
Затем я устанавливаю для needDisplayLoader значение NO, прежде чем отклонять представление Loader
Надеюсь, что это поможет...
Ответ 12
Я столкнулся с этой проблемой только сейчас и исправил ее с помощью селектора: afterDelay предложение выше. Просто чтобы добавить, я скомпилировал (без исправления) под iPhone OS 4.0 beta и NO CRASH! Итак, ошибка в XCode, по-видимому, была исправлена в следующем поколении. Не то, чтобы это никому из нас не было сегодня хорошо, но, как вы все знаете, это действительно было ошибкой в Xcode, и не обязательно, что мы делали неправильно в наших стилях кодирования.
Ответ 13
Была такая же проблема. Решил его с предложенным выше...
[self performSelector:@selector(doit) withObject:nil afterDelay:0.5];
Пришлось использовать задержку в 0,5 секунды. Возможно, потому, что я выполнял presentModalViewController непосредственно после модальности UIPickerViewController.
Ответ 14
У меня просто была эта проблема, и оказалось, что моя проблема была в том, что я был dealloc моим делегатом протокола.
Ответ 15
Я думаю, что причиной цикла является то, что новый контроллер просмотра, который вы загружаете, имеет метод viewDidAppear по умолчанию и имеет
[super viewDidAppear animated];
что означает, что он снова вернется к вашему главному виду viewDidAppear, так как он будет продолжать цикл
в представлении Viewcontroller, который вы представляете, есть метод, подобный этому, без супер viewdidapper:
-(void)viewDidAppear:(BOOL)animated{
//[super viewDidAppear:animated]; no super
}
Ответ 16
EXC_BAD_ACCESS
- ошибка памяти. Вероятно, вы пытаетесь использовать объект, который уже был выпущен/освобожден. Этот ответ дает несколько советов по отладке этих проблем:
Отладка EXC_BAD_ACCESS