2010-01-05 2 views
0

일부 문자열 메시지를 표시하기 위해 UITableView를 사용하고 NSOperationQueue를 사용하여 백그라운드 스레드에서 메시지를 가져 오는 사용자 지정된 NSOperation을 보유합니다. 한 메시지를 성공적으로 가져 오면 사용자 정의 된 NSOperation이 UITableView 컨트롤러에이를 표시하도록 알립니다.탐색 표시 줄에서보기를 전환하는 동안 EXC_BAD_ACCESS 오류없이 NSOperationQueue 스레드를 안전하게 종료하는 방법

모든 메시지가로드 된 후 UITableView에서 다른보기로 전환하기 위해 탐색 모음의 뒤로 버튼을 클릭하면 모든 것이 정상입니다. 하지만 일부 메시지가로드되는 동안 뒤로 버튼을 클릭하면 EXC_BAD_ACCESS가 throw됩니다. 나는 사용자 정의 NSOperation이 performSelectorOnMainThread 메서드로 UITableView 컨트롤러에 알리는 동안 예외가 발생했는지 확인했다. 보기 전환 후 대상 UITableView 컨트롤러가 유효하지 않은 것처럼 들리지만 Navigation Controller가 View Controller 인스턴스를 보유 할 것으로 생각됩니다. 이 문제를 해결하는 방법을 알고 싶습니까? 감사.

사용자 지정 작업은 다음 코드를 사용하여 jQuery과 컨트롤러 초기화 :

StatusMessageLoadingOperation *operation = [[StatusMessageLoadingOperation alloc] 
              initWithData:person 
              messageArray:cachedStatusMessages 
              target:self 
              action:@selector(didFinishStatusMessages:)]; 
[operationQueue addOperation:operation]; 
[operation release]; 

다음 코드를 사용하여 jQuery과 업데이트됩니다 맞춤형 NSOperation 클래스 :

- (void)main{ 
    for (int i = 0; i < [[person statusMessages] count]; i++) { 
     [target performSelectorOnMainThread:action withObject:messageArray waitUntilDone:NO]; 
    } 
} 

답변

0

당신이 당신의 viewWillDisappear 방법에 [operationQueue cancelAllOperations]를 호출 시도 되세요 ?

+0

viewWillDisappear에서 [operationQueue cancelAllOperations]를 호출하는 경우 [super isCance lled] 사용자 정의 NSOperation 클래스의 주 기능에서 취소 된 경우 performSelectorOnMainThread를 호출하여 tableview의 UI를 업데이트하지 마십시오. 뷰 컨트롤러를 팝하는 동안 tableview의 -deallock 메서드가 호출되기 때문에 tableView의 컨텍스트가 파괴되었습니다. (Alex Reynolds의 대답 참조). Frank와 Alex 덕분에 내 문제가 완벽하게 해결되었습니다. – Yanhua

0

보기 컨트롤러가 터지기 때문에 해당 컨트롤러의 -dealloc 메서드가 호출되므로 너무 빨리 큐를 해제하고 응용 프로그램의 다른 일부가 더 이상 존재하지 않는 큐 또는 큐에 액세스하려고 할 수 있습니다.

내 추천은 NSOperationQueue *myQueue 인스턴스를 응용 프로그램 대리인에 넣는 것입니다.

앱 대표단의 -applicationDidFinishLaunching:-dealloc 메소드를 사용하여 큐와 그 내용을 초기화하고 해제하십시오.

큐를 뷰 컨트롤러에서 분리하면 탐색 스택에서 뷰 컨트롤러를 팝 아웃 할 때 큐가 해제되지 않습니다. 그것과 나머지 작업은 나머지 응용 프로그램에서 계속 사용할 수 있어야합니다.

보다 쉽게 ​​설정, 다음 매크로 정의하여 대기열에 액세스 할 수 있도록 : 다음과 같이

#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate) 

당신은 다음 대기열에 액세스하기 위해 매크로를 사용할 수를 예 :

NSLog(@"%@", [[UIAppDelegate myQueue] operations]); 

또는 예 :

[[UIAppDelegate myQueue] addOperation:myOperation]; 
관련 문제