2013-10-10 4 views
2

서버에서 이미지를 다운로드하여보기에 표시하는 애플리케이션을 수행하고 있습니다. 나는 위임을 사용하고 있습니다. 이미지로드가 완료되면 대리자는 뷰에 메시지를 보내 이미지를 표시합니다.할당 취소 된 인스턴스에 메시지가 전송되었습니다. ARC

위의 시나리오가 정상적으로 작동합니다. 그러나 특정보기에서 다른보기로 이동하면 이미지로드가 끝나면 대리인이 메시지를 보내려하고 오류가 발생합니다.

내가보기 didUnload에

imageFetcher.delegate=nil; 

을 설정했습니다. 또한 다운로드 클래스에서 대리자 메서드를 호출하기 전에 대리자가 nil인지 확인합니다.

하지만 대리자 개체가 0이 아닌 것을 알 수 있습니다.

if(delegate!=nil) 
{ 
    [delegate imagefetcherView:self didLoadImage:image]; 
} 

어떻게이 오류를 해결할 수 있습니까?

감사 6+ 아이폰 OS에서 호출

+0

당신은 viewDidUnload 호출이 귀하의 코드입니까? 나는 그것이 최신 IOS 버전에서 가치가 떨어지는 메소드를 호출 할 수 없다고 생각한다. https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html – Tirth

답변

7

정리 작업을 수행 할 viewDidUnload을 의존하지 마십시오 사용해야합니다. 이는 iOS 6 이전의 iOS 버전에서만 호출되며,보기가 메모리 부족으로 인해 언로드 될 때만 표시됩니다. 단,보기를 닫거나 팝업 할 때가 아닙니다.

dealloc 메서드 또는 viewDidDisappear 또는 해당하는 곳에서 대리인을 설정하십시오. 현재 한 경우에도

  1. 당신이 현재/다른보기 컨트롤러를 밀어 경우 viewWillDisappearviewDidDisappear도 호출됩니다주의하십시오 : 당신은거야 nildelegate이 방법 따기 관련

    두 가지주의 사항 아직 해산되지 않았다. 해당 뷰 컨트롤러가 다른 뷰 컨트롤러를 푸시/프리젠 테이션하지 않는 경우에만 이러한 사라 관련 메서드를 사용하십시오.

  2. dealloc 기술을 사용의 delegate 이미지 가져 오기 클래스의 weak 재산이있을 경우에만 작동합니다 (위임은 일반적으로 weak해야합니다) 참고하십시오. delegatestrong 또는 retain 속성 인 경우보기 컨트롤러의 dealloc이 계속 호출되지 않습니다.

그런데 나는보기 컨트롤러가 해제 되었더라도 이미지를 계속 가져 오도록하고 있습니다. 위임자 인 nil뿐 아니라 요청을 취소 할 수도 있습니다. 이는 (a) 사용자가 취소를 허용하는 가져 오기 (예 : NSURLConnectionDataDelegate 접근 방식 또는 AFNetworking 작업)를 사용하고 있는지 여부와 (b) 취소 여부를 결정합니다. 하지만 사용자가 더 이상 필요하지 않더라도 요청을 계속할 수있게하는 소중한 네트워크 리소스 (느린 셀룰러 연결 인 경우)를 묶는 것이 쉽습니다. 그것은 귀하의 애플 리케이션의 세부 사항에 따라 다릅니다.

에 관계없이 viewDidUnload에 의존하지 마십시오.

+3

ARC에서 dealloc이 여전히 호출된다. , 당신은 그냥 그걸 풀 수 없거나'[super dealloc]'을 호출합니다. – Shubhank

+5

@giorashc 불쾌감은 없지만 그럴 수는 없습니다. 'dealloc'은 여전히 ​​ARC에서 사용 가능합니다. 유일한 단점은 Dante가 말했듯이, 당신은'[super dealloc] '이라고 부르지 않는다는 것입니다. ARC에는 (멤버가 일반적으로 할당 취소되므로) 종종 'dealloc'이 필요하지 않지만, 여전히 dealloc 메소드를 사용할 수 있습니다. – Rob

+1

아무도 찍히지 않고 내 마음이 날아 갔다. :) 그걸 살펴본 후에 정말로 dealloc을 구현할 수있다. ARC를 배울 때 dealloc이 금지되어 있음을 잘못 이해했습니다. 그 문제를 해결해 주셔서 감사합니다. – giorashc

3

viewDidUnload 밤은.

당신이

-(void)viewWillDisappear:(BOOL)animated{ 
    [super viewWillDisappear:animated]; 
    imageFetcher.delegate=nil; 
} 
0

클래스에서 여전히 dealloc 호출을 가질 수 있지만 [super dealloc]을 호출하면 안됩니다. 추가 할 경우 여기에 중단 점을 설정하고 유지 수를 0으로 가져 오는 위치를 확인할 수 있습니다. 또는 계측기를 사용하여 컨트롤러의 유지/릴리스주기를 추적 할 수 있습니다.

0

케어 뷰 컨트롤러에서 그림을 임시로 저장하기 위해 별도의 캐시를 구현할 예정이지만 할당 취소 된 컨트롤러는 그림을 다시 사용할 수 있습니다. 사용자가 같은 페이지로 돌아 오는 경우

그런 경우, 수명이 긴 캐시 오브젝트는 delegate으로 표시됩니다. 예를 들어보기 컨트롤러는 수신 컨트롤러가 표시 될 때 들어오는 사진에 대한 키 - 값 알림을 수신하기 위해 구독 할 수 있습니다 (KVO 수신 거부를 잊지 마세요. viewWillDisappear).

컨트롤러가 보이지 않지만 다시 표시 될 가능성이있는 경우 캐시에 사진이 있습니다 (메모리가 부족한 경우 삭제됩니다). 물론 사진을 다시 표시하고 사진을 드롭하지 않을 수도 캐시에서 확인할 수 있습니다.

관련 문제