모달 뷰 컨트롤러를 표시할 때 iPhone이 충돌함
-
05-07-2019 - |
문제
다른 보기가 모달 방식으로 표시된 직후에 모달 보기를 표시하려고 합니다(두 번째 보기는 표시되는 로딩 보기입니다).
- (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에서 동일한 오류를 재현했다고 생각합니다.내 응용 프로그램에서는 첫 번째 모달 보기를 표시한 후 즉시 두 번째 모달 보기를 표시하려고 하면 충돌이 지속적으로 발생했습니다.나는 미친 듯이 몇 시간 동안 애썼다.
이 스레드의 게시물을 읽은 후 Tab Bar Application 템플릿을 사용하여 간단하고 재현 가능한 예제를 만들려고 했습니다."FirstViewController.m"의 버튼 클릭에 응답한 후 UIImagePickerController를 사용하여 첫 번째 모달 보기를 표시할 수 있었습니다.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
도움이 되었기를 바랍니다.
** 앞에서 언급했듯이 isignoringintercationEvents를 사용하십시오
//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];
}
인터페이스 빌더에서 코드에 링크 된 버튼을 클릭 한 후이 문제가 발생하면 하나의 버튼에 링크 된 두 가지 작업이 있습니다 (버튼에 링크 된 모달 뷰가있는 경우 버튼을 복제 한 경우 그리고 다른 모달보기를 연결했습니다). 이것은 둘 다 해고하려고 시도하므로 그 메시지로 실패 할 것입니다.
나는 같은 예외를 발견했다
앱이 끊임없는 예외로 인해 앱 종료 'nsinternalinconsistency exception', 이유 : '전환이 이미 진행중인 동안 모달 전환을 시작하려고 시도합니다. 현재 전환이 완료되었는지 확인하려면 ViewDidAppear/ViewDidDisAppear를 기다립니다. '
앞서 제안한 바와 같이 나는 모달 전환을 제시하는 것을 지연 시키려고 노력했지만 실제로는 도움이되지 않았습니다. 나는 내가 가지고 있음을 발견했다 내 버튼의 TouchupInside 이벤트에 연결된 여러 IBActions !!!. 제 경우에는 두 가지 iBaction이 시작됩니다. 사람의 피커를 모드로 제시하고 이미지 선택기를 모드로 제시합니다. 이것은 오류 메시지를 설명합니다. 여러 IBActions가 연결되어 있는지 확인하십시오!
귀하의 문제는 ViewDidAppear가 In Init/ViewDidload/ViewWillAppear 메소드의 LoadViewController에 포함 된 메소드를 제공하는 메소드에있을 가능성이 높습니다.
중단점을 설정하고 충돌이 될 때까지 따라야합니다 ...
a를 클릭 할 때 비슷한 오류가있었습니다 UIButton
a 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];
}
이렇게하면 응용 프로그램을 시작하면 플립 사이드 뷰가 즉시 활성화됩니다. Flipside-View에서 "완료"버튼을 누르 자마자 ViewDidAppear를 다시 발사하고 Flipside-View로 돌아갑니다. Flipside -View가 표시 되 자마자 응용 프로그램이 중지됩니다. 메모리 거래가 호출되지 않습니다. 홈 버튼을 누른 것과 같습니다.
이러한보기에서 몇 가지 추가 속성을 사용할 때 예외도 얻었으므로 코드를 최소 금액으로 제거했습니다 ...
나는 정말로 단서가 없다.이 문제는 실제로 ...
안부, 토비아스
그것은 실제로 지원 루틴에 달려 있습니다 viewDidAppear
하고있다. 예를 들어, if presentModalViewController:animated:
유지하지 않습니다 loader
충돌은 그로 인한 것일 수 있습니다 UIWindowController
이야기하려고합니다 loader
이후 출시되었습니다 (게시 한 루틴의 끝에 게시).
로딩 뷰를 구현하는 것과 동일한 기술을 사용하는 동안 비슷한 문제가있었습니다. 하중이 끝날 때 로딩 뷰가 기각되면 충돌이 발생합니다. 제 경우에는 로딩 뷰가 기각 되 자마자 ViewDidAppear가 다시 호출되어 로딩 뷰를 다시 제시하려고 시도했는데, 아마도 충돌이 발생했을 것입니다. 로딩 뷰가 이전에 제시되었는지 확인하여 간단히 고정했습니다.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if(needDisplayLoader)
[self presentModalViewController: loader animated:NO];
}
그런 다음 로더 뷰를 기각하기 전에 NeedDisplayLoader를 NO로 설정했습니다.
도움이 되었기를 바랍니다...
나는 지금이 문제를 해결하고 위의 선택자 : Afterdelay 제안을 사용하여 수정했습니다. 추가하기 위해 iPhone OS 4.0 베타에서 (수정없이) 컴파일을했으며 충돌이 없습니다! 따라서 Xcode의 버그는 다음 세대에서 고정 된 것으로 보입니다. 이것이 오늘날 우리에게는 좋은 일을하는 것이 아니라, 당신이 알고 있습니다. ~였다 Xcode의 버그와 코딩 스타일에서 우리가 잘못하고있는 것은 아닙니다.
똑같은 문제가있었습니다. 위의 제안으로 해결했습니다 ...
[self performSelector:@selector(doit) withObject:nil afterDelay:0.5];
0.5 초 지연을 사용해야했습니다. 아마도 UIPICKERVIEWCONTROLLER MODAL 직후 PRESSEMODALVIEWCONTROLLER를 수행했기 때문일 수 있습니다.
방금이 문제가 있었는데 내 문제가 내 프로토콜 대의원을 다루기 때문이라는 것이 밝혀졌습니다.
루프의 이유는로드중인 새 뷰 컨트롤러가 기본적으로 viewDidAppear 메소드를 가지고 있기 때문이라고 생각합니다.
[super viewDidAppear animated];
즉, 메인 뷰 컨트롤러의 ViewDidAppear로 다시 호출됩니다.
ViewController에서는 Super ViewDidapper가없는 이와 같은 방법이 있습니다.
-(void)viewDidAppear:(BOOL)animated{
//[super viewDidAppear:animated]; no super
}
EXC_BAD_ACCESS
메모리 오류입니다. 이미 해제/거래 된 객체를 사용하려고 할 것입니다. 이 답변은 이러한 문제를 디버깅하기위한 몇 가지 팁을 제공합니다.