2011-07-28 3 views
3

(내 생각 엔) : vc가 팝 된 후 (dealloc에서) ASIHTTPRequest 대리자/NSOperationQueue 대리자를 nil로 설정합니다.ASIHTTPRequest 및 좀비 ...

시작하기 전에 this 질문은 비슷하지만 동일하지 않습니다.

내 앱은 출시 된 버전과 거의 비슷하지만 개발 과정에서 존재했던 유일한 영구 버그입니다. 또한 누군가에게 앱을 데모 할 때 발생하는 유일한 버그이기도합니다.이 버그로 인해 앱이 종료되기 때문에 매우 당황 스럽습니다. 누군가가 이것을 위해 문제를 발견 할 수 있다면, 나는 적당한 크기의 현상금을 수여 할 것이다. 질문의


시작하십시오 ASIHTTPRequest 좀비 인 객체에의 requestFinished 선택기를 호출하려고했을 경우에

기본적으로,이 버그가 발생합니다.

좀비에게 셀렉터를 보냈을 때 ASIHTTPRequest가 좀비가 아닌 비슷한 개체로 보낼 것이라고 생각합니다. 나는 그것을 보내려는 컨트롤러의 CALayer에 셀렉터를 보내고, 내 UINavigationButton으로 보내지는 것은 꽤 일반적이라고 들었다. - 아무튼, 이것의 효과는 그것이 예외를 throw한다는 것입니다. - 내가 무엇을 왜 퍼즐

이 코드 줄이가 실패 하나입니다
[queue performSelector:@selector(requestFinished:) withObject:self]; 

: 그것은 'requestFinished'선택 호출하려고했을 경우에

문제는 ASIHTTPRequest 클래스 내부에서 발생? 내가 연결된 질문에서, OP는보기 컨트롤러에서 [self retain]을 호출하여 해결했다고 말했다. 확실하게 그것이 옳지 않은가?

구조

방법 내 ASIHTTPRequest의 작품은, 그들은 내 애플 대리자 내에 상주하는 downloadQueue (NSOperationQueue)에 추가됩니다. 내 응용 프로그램의 구조/스타일은 주로 this sample code을 기반으로합니다. 매우 비슷한 일을하지만 flickr RSS 피드를 사용합니다.

ASIHTTPRequest를 사용하는 내 응용 프로그램 섹션은 웹캠 뷰어입니다. 그것은 3 개의 웹캠을 표시하는 테이블보기가있는 탐색 컨트롤러가 있습니다. 이 이미지는 JPEG이며 30 초마다 (원격 서버의) 정적 파일로 업데이트됩니다. 이 테이블 뷰 내의 셀은 사용자 정의이며 각 셀은 자체 ASIHTTPRequest를로드합니다. 셀이 각각의 이미지를 다운로드하여 표시합니다. 이들 세포 중 하나가 선택된다

- (void)loadURL:(NSURL *)url { 
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url]; 
    [request setDelegate:self]; 
    [request setDidFinishSelector:@selector(requestDone:)]; 
    [request setDidFailSelector:@selector(requestWentWrong:)]; 
    NSOperationQueue *queue = [[MyAppDelegate sharedAppDelegate] downloadQueue]; 
    [queue addOperation:request]; 
    [spinner startAnimating]; 
    [self addSubview:spinner]; 
    [request release]; 
} 

, 그것은 ASIHTTPRequest의 다른 인스턴스가로드 상세보기로 사용자를 취 여기

내 각각의 셀에서 호출 I 만든 방법 그러면 선택한 웹캠의 이미지가 다운로드됩니다.

버그가 정상에서

을 트리거 방법 "진정"내 응용 프로그램의 사용은, 그것을 잘 작동합니다. 이 문제는 이러한 뷰 (루트 및 세부 웹캠 뷰 간)에서 신속한 푸시 및 팝핑이 발생할 때 발생합니다.세부 정보보기를 입력하고 진행률 표시 줄이 움직이기 시작하면 루트로 다시 팝업됩니다. 이것은 내가 ASIHTTPRequest가 끝나고 컨트롤러를 호출하려고 시도 할 때 컨트롤러가 활성화되지 않았기 때문에 실패했다고 생각합니다.

충돌 로그

Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000480 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib     0x30183f24 objc_msgSend + 24 
1 iCompton      0x0003c4d4 0x1000 + 242900 
2 CoreFoundation     0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18 
3 iCompton      0x00029082 0x1000 + 163970 
4 CoreFoundation     0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18 
5 Foundation      0x33fd3e66 __NSThreadPerformPerform + 266 
6 CoreFoundation     0x35ebc8ca __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 8 
7 CoreFoundation     0x35e8cec6 __CFRunLoopDoSources0 + 378 
8 CoreFoundation     0x35e8c6f2 __CFRunLoopRun + 258 
9 CoreFoundation     0x35e8c504 CFRunLoopRunSpecific + 220 
10 CoreFoundation     0x35e8c412 CFRunLoopRunInMode + 54 
11 GraphicsServices    0x35261d1c GSEventRunModal + 188 
12 UIKit       0x33865574 -[UIApplication _run] + 580 
13 UIKit       0x33862550 UIApplicationMain + 964 
14 iCompton      0x00002b92 0x1000 + 7058 
15 iCompton      0x00002b44 0x1000 + 6980 

  • 덕분에 당신은 여기까지 읽으면! 당신은 내 문제 : 당신은 라이브 애플리케이션에 NSZombieEnabled를 사용해서는 안

답변

6

세부 정보보기를 입력하면 진행률 표시 줄이 움직이기 시작하고 다시 루트로 팝업됩니다. 이것은 내가 ASIHTTPRequest가 끝나고 컨트롤러를 호출하려고 시도 할 때 컨트롤러가 활성화되지 않았기 때문에 실패했다고 믿는다.

나는이 문제를 제대로 파악하고 있다고 생각합니다.

루트 컨트롤러 (또는 다른 컨트롤러)에 팝업 할 때 ASIHTTPRequest를 취소해야합니다. 요청을 취소하기 전에 그 delegate을 nil로 설정해야합니다. 또는 clearDelegatesAndCancel을 사용할 수 있습니다.

아마도이 경우 뷰 컨트롤러에서 요청에 대한 참조를 유지해야하지만 이는 문제가되지 않습니다.

재미있는 S.O. 팝업되는 UIViewController에 대한 질문/답변은 here입니다. 당신의 ViewController의 dealloc 방법 nil에 미결제 ASIHTTPRequest의의 delegate을 설정 : 여기

+0

안녕하세요, 괜찮습니다. 각 웹캠이 동일한 세부 컨트롤러를 사용하므로 요청을 무시할 수 있습니다. 요청을 저장하려고하면 무의미합니다. 어쨌든, 당신은 어떻게 pop (단지 viewWillDisappear가 아니라)을 감지합니까? –

+0

요청을 취소 할 수 있는지 이해하지 못했다. 어쨌든 나는 내 대답을 편집하여 팝업을 발견하는 것에 대한 정보를 추가했다. – sergio

+0

미안하지만 '요청을 파기 함으로서'위임을 제거했다. –

0

를 해결하는 경우가

  • 바운티 대답 경우
  • 덕분에 더는 메모리가 해제되지 않습니다. 개발 중에 있지 않을 때 해제해야합니다. 급하게 밀고 당기는 것은 아마도 메모리를 소모하고, 메모리 경고를 유발하며, 물건을 방출하고 해제하게 만듭니다. 충돌 로그를 게시 할 때까지는 알 수 없습니다.

  • +0

    나는 한 번만 악기를 통해 좀비를 테스트했습니다 ... 나는 좀비라는 용어를 과도하게 사용 된 객체를 참조하기 위해 사용합니다. 지금 오류 로그를 게시합니다. –

    0

    내가이 문제를 해결하는 방법입니다.

    의 ViewController는 탐색 스택 dealloc 'D 팝된 된 후 didFinishSelector의 상기의 ViewController에 didFailSelector 등의 메시지를 보내는 뛰어난 ASIHTTPRequest들 막았다.

    은 유의 사항 : cancelAllOperations 가능성이 비동기 didFailSelector 호출 ASIHTTPRequest 방법. 이 경우 더 이상 존재하지 않는 viewController에서 선택자 으로 호출 될 수 있습니다.