UIAlertView의 Delegate 이벤트가 제대로 진행되지 않아 며칠간의 디버깅(삽질)끝에 찾아냈다.
개발에서 노하우 정말 중요하다.
clickedButtonAtIndex ==> didDismissWithButtonIndex 로 수정하여 해결.
아래는 고마운 글.
문 제
UIAlertView 메세지를 출력하는 도중 Home 버튼과 같이 예외 상황이 경우 UIAlertView의 Delegate 이벤트가 제대로 진행되지 않은 현상
현 상
문제 소스
{
//마지막에
if(NaNetworkReachable() == NO)
{
[i_downloader stop];
NaMessageViewWithOneButton(Na_STR_ERROR_NO_NETWORK, @"확인", self);
return;
}
i_progressView.downloadAllNum = allSpot+i_downedNum;
i_progressView.downloadNum = allSpot+i_downedNum;
i_downloading = NO;
WSTown *town = [getThemeCountWithTownId(i_downloadTownId, i_downloadCityId) retain];
[SQLiteForWingSpoon updateTownInformation:i_downloadTownId
spotCount:town.i_spotCount
themeCountArray:town.i_themeArray
updateDate:nil valid:2];
[SQLiteForWingSpoon updateCityInformation:i_downloadCityId
valid:2];
[town release];
NaMessageViewWithYesNoButtonWithDelay([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1, 0.1);
}
다운로드를 받고 완료 메세지(NaMessageViewWithYesNoButtonWithDelay)를 출력하는 도중 Home버튼을 누르게 되면 아래와 같은 순서로 이벤트가 발생하였다.
1. 다운로드 완료 처리 중(spotDownloader 진행 중)
2. 홈 버튼 클릭
2. UIAlertViewDelegate - willPresentAlertView (Background로 가기전에 AlertView가 준비상태로 돌입)
3. AppDelegate - applicationDidEnterBackground (Background 상태)
4. 앱 재 실행
5. UIAlertViewDelegate - didPresentAlertView (Foreground 이전에 AlertView가 표시)
6. AppDelegate - applicationWillEnterForeground (Foreground 상태가 됨)
6. UIAlertViewDelegate - didDismissWithButtonIndex (AlertView가 저절로 닫힘)
이런순으로 Delegate가 진행되어 문제가 발생되었다. 즉 Foreground 이전에 didPresentAlertView가 호출되어 이미 메세지가 뜬 상태로 있다가 Foreground 호출 이후 didDissmissWithButtonIndex가 호출되어 메세지 창이 저절로 닫혀버리는 현상이다. 더욱이 이런게 닫힌 창이 다른 UIAlertView가 호출될 때 갑자기 나타나는 것이다. 그로 인해 원래 UIAlertView에서 호출되어 처리되어야 하는 View가 아닌 다른 view에서 호출되어 BAD_EXCEPTION 발생하는 문제가 생겼다. (어떤 경우에는 6번 과정 이후 자동으로 다시 willPresentAlertView가 호출되어 다시 출력되어 문제가 안생기는 경우도 있으나 위 상태에서 중단 되는 경우가 문제 였다)
해결방법
1. didDismissWithButtonIndex 이벤트가 발생될 때 매개변수로 넘어오는 alertView의 객체 상태로 비정상 닫기 인지 정상 닫기 인지 구분하는 방법을 찾았다.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
alertView == nil 인 경우 정상 닫힘
alertView != nil 인 경우 비정상 닫힘
2. UIAlertView 내 dismissWithClickedButtonIndex 메시지를 호출하여 AlertView를 다시 출력 안되게끔 막는다.
-> UIAlertView 내 메시지들을 찾아보다가 위 메시지의 역할이 사용자의 Action 없이 AlertView를 닫히게하는 기능이 있다는 것을 깨닫고 비정상 닫힌 경우 위 메시지를 호출하여 다른 UIAlertView와 중복 호출이 안되게 끔 방지하였다
3. 마지막으로 닫혀버린 UIAlertView 메시지를 다시 출력하여 사용자가 AlertView 이상 동작을 못느끼게 재실행한다
{
if(alertView.superview != nil){
// 기존에 비정상 UIAlertView를 오작동 출력을 방지함
[alertView dismissWithClickedButtonIndex:buttonIndex animated:NO];
// 메시지 재출력
NaMessageViewWithYesNoButton([NSString stringWithFormat: Na_STR_OK_DOWNLOAD, [i_downloadTargetTown i_name] ], self, 1);
}
}
출처: http://devnote2.tistory.com/32
'Scrapbook > 개발 및 프로그래밍' 카테고리의 다른 글
ASP.NET Web Service wsdl.exe utility (0) | 2013.09.10 |
---|---|
이전 프로젝트 아이폰5 해상도 대응 (0) | 2013.01.08 |
스마트폰 디바이스별 사이즈(해상도) (4) | 2012.08.22 |
종목발굴 (0) | 2012.02.12 |
Converting DOS Batch Files to Shell Scripts (0) | 2011.10.14 |