-dealloc이 아닌-(void) viewDidUnload에서 언제 객체를 해제해야합니까?


답변:


51

이미 표시된 것 외에도 -viewDidUnload.의 논리에 대해 더 자세히 설명하고 싶었습니다 .

이를 구현하는 가장 중요한 이유 중 하나는 UIViewController하위 클래스가 일반적으로 뷰 계층 구조의 다양한 하위 뷰에 대한 소유 참조를 포함 하기 때문입니다 . 이러한 속성은 IBOutlets펜촉에서로드 할 때를 통해 설정 하거나 -loadView예를 들어에서 프로그래밍 방식 으로 설정할 수 있습니다 .

하위 뷰의 추가 소유권은 뷰가 UIViewController뷰 계층 구조에서 제거되고 메모리를 절약하기 위해 해제 된 경우에도 뷰에 의해 하위 뷰가 해제되는 경우에도 UIViewController그 자체가 여전히 자체 미해결을 포함하고 있기 때문에 실제로 할당 해제되지 않습니다. 해당 개체에 대한 참조도 유지합니다. UIViewController이러한 개체 의 추가 소유권을 해제하면 메모리를 확보하기 위해 할당이 해제됩니다.

여기서 해제하는 객체는 일반적으로 Nib 또는의 구현을 통해 UIViewController뷰가 있을 때 다시 생성되고 다시 설정됩니다 .re-loaded-loadView

또한 UIViewController view속성은 nil이 메서드가 호출 될 때입니다.


1
보기 /보기 컨트롤러 수명주기를 이해하려면 developer.apple.com/library/ios/#featuredarticles/… 를 읽어야 합니다.
Paul Solt

21

현상태대로 설명서를 말한다 :

뷰 컨트롤러가 메모리를 확보하기 위해 뷰 및 해당 뷰와 관련된 모든 객체를 해제해야 할 때 메모리 부족 상태에서 호출됩니다.

같은 상황에서 dealloc되어 있지 했다. 이 방법은 OS3 이상에서만 사용할 수 있습니다. iPhone OS 2.x에서 동일한 상황을 처리하는 것은 정말 고통 스러웠습니다!

2015 년 7 월 업데이트 : viewDidUnload"보기가 더 이상 메모리 부족 조건에서 제거되지 않으므로이 메서드가 호출되지 않기 때문에"iOS 6에서 더 이상 사용되지 않는다는 점에 유의해야합니다 . 따라서 현대적인 조언은 그것에 대해 걱정하지 않고 dealloc.


6
또한 문서에서 : "viewDidLoad 메서드 또는 응용 프로그램의 다른 부분에서 나중에 쉽게 다시 만들 수있는 개체에 대해서만이 작업을 수행해야합니다.이 메서드를 사용하여 사용자 데이터 또는 다른 정보를 해제해서는 안됩니다. 쉽게 재현 ". 나 자신도 질문을 던졌습니다. 감사합니다!
leolobato

현재보기가 표시되면 어떻게됩니까? 메모리 부족 경고 때문에 삭제하는 것이 나쁘지 않습니까? ;) 그러면 앱은 비어있을뿐입니다. 메모리 부족으로 인해 뷰를 해제 할 수 없습니다. 뷰가 보이지 않으면 항상 전체 컨트롤러를 해제합니다. Althogh에는 그대로 유지되고 자식 뷰 컨트롤러의 모든로드 / 언로드를 관리하는 루트 뷰 컨트롤러가 있습니다.
감사합니다

아니요, 한보기를 다른보기로 바꾸면이 기능을 사용하지 않습니다. UINavigationController를 사용하여 뷰의 "스택"이있는 경우를 생각해보십시오. 하나의보기 만 표시되며 메모리 경고가있는 경우 표시되지 않는 모든보기를 해제 할 수 있습니다.
Stephen Darlington

Thanks가 지적한 것처럼 현재 보이는 뷰에서 viewDidUnload가 호출되지 않도록 어떻게 제어합니까?
arielcamus 2010 년

1
viewDidUnload는 현재 보이는 뷰에서 호출되지 않고 보이지 않는 뷰에서만 호출됩니다.
progrmr

9

이는 일반적으로 @propertyas를 설정하기 때문에 "(nonatomic, retain)"생성 된 setter가 현재 개체를 해제 한 다음 인수를 유지합니다.

self.property = nil;

... 다음과 같은 작업을 수행합니다.

[property release];
property = [nil retain];

따라서 당신은 하나의 돌로 두 마리의 새를 죽이고 있습니다 : 메모리 관리 (기존 객체 해제)와 포인터를 nil에 할당합니다 (모든 메시지를 nil 포인터에 보내면 nil이 반환되기 때문입니다).

도움이 되었기를 바랍니다.


8

viewDidUnload이것은 뷰가 아니라 뷰 컨트롤러의 메서드 라는 것을 기억하십시오 . 뷰의 dealloc 방법은 전화를받을 때보기 언로드하지만, 뷰 컨트롤러의 dealloc 방법은 나중에까지 호출 할 수 없습니다.

메모리 부족 경고가 표시되고 뷰가 표시되지 않는 경우, 예를 들어 UIImagePickerController를 사용하여 사용자가 사진을 찍을 때마다 발생하는 경우 뷰가 언로드되고 그 후에 다시로드되어야합니다.


말이 되네요. 항상 전체 뷰 컨트롤러를 삭제하면 어떻게 되나요? 그것이 제가 실제로하는 일입니다. 이 경우 -viewDidUnload를 많이 다룰 필요가 없습니다. 그렇죠? 뷰만 삭제하는 상황은 없었습니다. 어차피 보이지 않으면 항상 전체 컨트롤러를 삭제했기 때문입니다.
감사합니다

음,보기가 표시되지만 그 위에 ImagePicker와 같은 전체 화면보기가있는 경우에는 계획하지 않았더라도보기가 언로드 될 수 있습니다.
David Maymudes

6

결론:

뷰 컨트롤러에는 뷰 속성이 있습니다. 일반적으로 펜촉 또는 코드 조각은이보기에 다른보기를 추가합니다. 이것은 종종 다음과 같이 -viewDidLoad 메소드 내부에서 발생합니다.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createManyViewsAndAddThemToSelfDotView];
}

또한 nib 파일은 버튼을 생성하여 뷰 컨트롤러의 뷰에 추가 할 수 있습니다.

iPhone OS 2.2에서 -didReceiveMemoryWarning이 시스템에서 호출되었을 때 메모리를 확보하기 위해 무언가를 해제해야했습니다. 이해가된다면 전체 뷰 컨트롤러의 뷰를 해제 할 수 있습니다. 또는 메모리를 많이 사용하는 콘텐츠입니다.

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

이제 새로운 OS 3.0에는 -viewDidUnload 메서드가 있습니다.이 메서드는 메모리 부족으로 인해 뷰가 언로드되었을 때 시스템에서 호출됩니다.

-viewDidUnload는 뷰 컨트롤러 자체와 뷰가 소유 한 모든 개체를 해제하는 데 사용됩니다. 이유 : 뷰 컨트롤러가 뷰의 자식에 대한 참조 (예 : 버튼)를 보유하는 경우, 참조 된 자식 뷰는 해제되지 않습니다. 유지 횟수가 1보다 크기 때문입니다. -viewDidUnload에서 해제 된 후 해제 될 수 있습니다. 기억으로부터.


1
remeber in view는 self.button = nil ;, [button release];가 아니라 언로드했습니다.
mk12

6

Apple은 viewWillUnload를 사용하지 않습니다. 이제 didReceiveMemoryWarning 또는 dealloc을 사용하여 objetc를 해제하십시오.

iOS 6에서 UIViewController의 viewWillUnload 및 viewDidUnload 메서드는 이제 더 이상 사용되지 않습니다. 이러한 메소드를 사용하여 데이터를 릴리스하는 경우, 대신 didReceiveMemoryWarning 메소드를 사용하십시오. 이 메서드를 사용하지 않는 경우 뷰 컨트롤러의 뷰에 대한 참조를 해제 할 수도 있습니다. 이 작업을 수행하기 전에보기가 창에 없는지 테스트해야합니다.


5

뷰 컨트롤러가 내비게이션 컨트롤러 스택에서 팝되고 다른 곳에서 유지되지 않으면 할당이 취소되고 viewDidUnload 대신 dealloc이 호출됩니다. dealloc의 loadView에서 생성 된 뷰를 해제해야하지만 dealloc이 호출 된 직후 변수가 더 이상 존재하지 않기 때문에 변수를 nil로 설정할 필요는 없습니다.


3

예를 들어 loadView 메서드에 유지 한 UIImageView 또는 해당 UIImageView에 있던 이미지와 같이 보유한 모든 하위 뷰를 해제 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.