2009-09-11 3 views
30

Я пытаюсь показать модальное представление прямо после того, как другой вид был представлен модально (второй представляет собой загрузочный вид, который появляется).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

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

- (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]; 
} 
+0

Просто где находится EXC_BAD_AC CESS из? Вы даете нам трассировку стека здесь, но я не уверен, что ошибка происходит в этом фрагменте кода. Можете ли вы отредактировать сообщение, чтобы дать нам полный журнал со следами, где были все потоки? –

+0

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

+0

Попробуйте положить 'loader' в пул авторефератов. Я думаю, что загрузчик слишком быстро исчезает, вероятно, потому, что текущий контроллер представления должен уйти с пути для нового контроллера представления и просмотра. Другие идеи: используйте отладчик и наблюдатель. Если это то, что вызывает проблемы, вы обнаружите это именно так.Если нет, держитесь в отладчике, и вы можете понять это. –

ответ

30

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

- (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

Человек, я пытался понять это на некоторое время. Спасибо за помощь! –

+1

Спасибо, спасибо, спасибо. Это меня убило. –

+2

Я подозреваю, что он будет работать и с задержкой 0.0f. В принципе, он будет представлен на следующей итерации runloop, по сути, мгновенно. –

-2

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

Debugging EXC_BAD_ACCESS

+2

У меня такая же проблема в минимальном тестовом приложении, и я знаю, что это не нормальная проблема с управлением памятью. –

0

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

+0

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

+1

Здесь есть два вида: один входит и один выходит - вы сохраняете оба до тех пор, пока переход не будет завершен? Возможно, есть проблема с сохранением обоих взглядов до тех пор. – fbrereto

1

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

Установите несколько точек останова и следовать до аварии ...

+0

Эти методы довольно пусты. Все, что я делаю, это изменить цвет фона на viewDidLoad :. Приложение выполняет эти строки в порядке, авария не возникает в моем коде, она сбой, когда другие вещи выполняются позже в цикле событий. –

1

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

Создать новый проект XCode «Утилита». В FlipsideViewController.m вы просто вставить следующий метод:

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

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

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

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

с наилучшими пожеланиями, Tobias

0

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

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

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

Тогда я поставил needDisplayLoader на NO до увольнения вида загрузчика

Надеются, что это помогает ...

0

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

5

Я считаю, что я воспроизвел ту же ошибку в 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 

Надеется, что это помогает.

0

Была такая же проблема. Решаемые его выше предложил ...

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

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

0

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

1

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

+0

Хороший ответ. Чтобы обобщить его: смотрите код, который открывает Modal View и убедитесь, что он вызывается только один раз. Не нужно нажимать кнопку. –

3

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

3

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

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

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

4

** Как было сказано ранее, использовать 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]; 
    } 
+0

Это работает в моем случае ... однако я не уверен, как он правильно проходит в «анимирующем» флаге ... скорее всего, он настроен на какое-то ненужное значение, которое оказывается ненулевым. –

+0

Спасибо. Это работало для моих нужд. –

+0

жизнь спасатель !! :) Это хорошо работает, если вы хотите представить представление из фонового метода. –

1

Я была такая же проблема, из-за несоответствия имен в

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

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

0

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

[super viewDidAppear animated]; 

, который означает, что он перезвонит viewDidAppear вашего основного контроллера представления снова, как что он будет идти на петле в ViewController

вы представляете есть метод, как это, без супер viewdidapper:

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

} 
Смежные вопросы