iOS UIViewController 라이프 사이클 이해하기


299

UIViewController라이프 사이클 을 관리하는 올바른 방법을 설명해 주 시겠습니까?

특히, 내가 사용하는 방법을 알고 싶습니다 Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnload및 DisposeA의 모노 터치의 메소드 UIViewController클래스입니다.


OSX ViewController 및 WindowController에 대한 정보 또는 링크가 있습니까? 공유하십시오.
— Anoop Vaidya

답변:


410

이러한 모든 명령은보기 컨트롤러를로드 / 표시 / 숨길 때 iOS에 의해 적절한 시간에 자동으로 호출됩니다. 이 방법들은 그 자체에 붙어 있고 붙어 UIViewController있지 않다는 점에 유의해야 UIView합니다. 를 사용하여 이러한 기능을 얻을 수는 없습니다 UIView.

Apple 사이트에는 훌륭한 설명서가 있습니다 . 간단히 말하면 :

  • ViewDidLoad-클래스를 생성하고 xib에서로드 할 때 호출됩니다. 초기 설정 및 일회성 작업에 적합합니다.

  • ViewWillAppear-보기가 나타나기 직전에 호출되며,보기가 표시되기 전에 매번 발생하고 싶은 필드 나 작업을 숨기거나 표시하는 데 좋습니다. 뷰 사이를왔다 갔다 할 수 있기 때문에 뷰가 화면에 나타나려고 할 때마다 호출됩니다.

  • ViewDidAppear -뷰가 나타난 후 호출됩니다. 애니메이션을 시작하거나 API에서 외부 데이터를로드하기에 좋은 장소입니다.

  • ViewWillDisappear/ DidDisappear- 동일 아이디어 ViewWillAppear/ ViewDidAppear.

  • ViewDidUnload/ ViewDidDispose-Objective-C에서이 부분은 정리 및 릴리스 작업을 수행하는 곳이지만 자동으로 처리되므로 실제로 수행해야 할 작업은 많지 않습니다.


86
이 텍스트는 ViewDidLoad를 한 번만 작업에 사용해서는 안되므로 약간 오해의 소지가 있습니다. 메모리 부족으로 인해 뷰가 언로드 된 후 다시로드되면 여러 번 호출 될 수 있습니다.
— Ricky Helgesson

4
뷰 컨트롤러를 생성 / 초기화 할 때 실제로 ViewDidLoad가 호출되지 않습니다. 뷰 컨트롤러의 뷰와 관련된 뷰를 처음 수행 할 때 호출됩니다. 서브 뷰로 추가하거나 프레임 등을 설정하는 것과 같이 펜촉에서로드 할 때도 호출됩니다.
— Jason Grandelli

3
ViewDidAppear-보기가 표시된 후 호출-애니메이션을 시작하거나 API에서 외부 데이터를로드하기에 좋은 위치입니다. 데이터로드를 시작하기에 좋은 이유는 무엇입니까? 왜 viewDidLoad가 아닌가?
— Anton Chikin

1
viewDidLoad 전에 메모리에 펜촉이로드 될 때 처음 호출되는 경우 loadView 메소드는 어떻습니까?
— iHulk

@ chakrit 이것은 좋은 지적입니다-viewDidAppear는 데이터를 새로 고칠 수있는 좋은 장소입니다 (필요한 경우). KVO는 사용자가 실제로 보지 않은 뷰에서 바람직하지 않은 새로 고침을 일으킬 수 있기 때문에 동의하지 않습니다.
— Anton Chikin

409

업데이트 : ViewDidUnload는 iOS 6에서 더 이상 사용되지 않으므로 그에 따라 답변을 업데이트했습니다.

UIViewController 라이프 사이클은 다음과 같습니다.

뷰 컨트롤러의 수명주기

Xamarin Native / Mono Touch를 사용하면 네이티브 API를 사용하므로 Apple 설명서에서 볼 수있는 것과 동일한 ViewController 수명주기를 따릅니다.


17
viewWillLayoutSubviews 및 viewDidLayoutSubviews는이 플로우 차트에서 어디로 이동합니까?
— Max_Power89

7
이 도표는 정확하지 않습니다. viewDidUnload는 iOS6부터 사용되지 않습니다 : stackoverflow.com/questions/12509102/…
— occulus

2
이것은 실제로 단순히 잘못 입니다. 몇 년이 지남에 따라 SO에 대한 잘못된 대답의 또 다른 예. 컴퓨팅은 비 정적입니다.
— Fattie

186

최신 iOS 버전 용입니다 ( Xcode 9.3, Swift 4.1로 수정 ). 다음은 전체 수명주기를 만드는 모든 단계입니다 UIViewController.

  • loadView()

  • loadViewIfNeeded()

  • viewDidLoad()

  • viewWillAppear(_ animated: Bool)

  • viewWillLayoutSubviews()

  • viewDidLayoutSubviews()

  • viewDidAppear(_ animated: Bool)

  • viewWillDisappear(_ animated: Bool)

  • viewDidDisappear(_ animated: Bool)

모든 단계를 설명하겠습니다.

1. loadView

이 이벤트는 컨트롤러가 관리하는보기를 생성 /로드합니다. 관련 nib 파일에서로드하거나 UIViewnull이 발견되면 비어 있을 수 있습니다. 이렇게하면 프로그래밍 방식으로 코드로 뷰를 만들 수 있습니다.

하위 클래스가 펜촉을 사용하지 않는 경우 사용자 정의 뷰 계층 구조를 만들어야하는 곳입니다. 직접 호출해서는 안됩니다. 프로그래밍 방식으로 뷰를 만들고 루트 뷰를 view속성에 할당 할 때만이 메서드 를 재정의하십시오. loadView 를 재정의 할 때 수퍼 메서드를 호출하지 마십시오.

2. loadViewIfNeeded

현재의보기가 viewController아직 설정되지 않은 경우이 방법은보기를로드하지만 기억하십시오. 이는 iOS> = 9.0에서만 사용할 수 있습니다. 따라서 iOS <9.0을 지원하는 경우 iOS가 그림에 올 것으로 기대하지 마십시오.

뷰 컨트롤러의 뷰가 아직 설정되지 않은 경우로드합니다.

삼. viewDidLoad

이 viewDidLoad이벤트는 뷰가 생성되어 메모리에로드 될 때만 호출되지만 뷰의 경계는 아직 정의되지 않았습니다. 뷰 컨트롤러가 사용할 객체를 초기화하기에 좋은 곳입니다.

뷰가로드 된 후 호출됩니다. 코드로 작성된 뷰 컨트롤러의 경우 -loadView 이후입니다. 펜촉에서 아카이브되지 않은 뷰 컨트롤러의 경우 뷰가 설정된 후입니다.

4. viewWillAppear

이 이벤트 viewController는 화면에보기가 나타날 때마다 알려줍니다 . 이 단계에서는보기에 정의 된 경계가 있지만 방향이 설정되지 않았습니다.

뷰가 표시 될 때 호출됩니다. 기본은 아무 것도하지 않습니다.

5. viewWillLayoutSubviews

이는 수명주기의 첫 번째 단계로 한계가 확정됩니다. 구속 조건 또는 자동 레이아웃을 사용하지 않는 경우 여기에서 하위보기를 업데이트 할 수 있습니다. iOS> = 5.0에서만 사용할 수 있습니다. 따라서 iOS <5.0을 지원하는 경우 iOS가 그림에 올 것으로 기대하지 마십시오.

뷰 컨트롤러의 뷰의 layoutSubviews 메소드가 호출되기 직전에 호출됩니다. 서브 클래스는 필요에 따라 구현할 수 있습니다. 기본값은 nop입니다.

6. viewDidLayoutSubviews

이 이벤트는 뷰 컨트롤러에 하위 뷰가 설정되었음을 알립니다. 서브 뷰를 설정 한 후에 변경하는 것이 좋습니다. iOS> = 5.0에서만 사용할 수 있습니다. 따라서 iOS <5.0을 지원하는 경우 iOS가 그림에 올 것으로 기대하지 마십시오.

뷰 컨트롤러의 view의 layoutSubviews 메소드가 호출 된 직후에 호출됩니다. 서브 클래스는 필요에 따라 구현할 수 있습니다. 기본값은 nop입니다.

7. viewDidAppear

viewDidAppear보기 후 이벤트가 발생이 화면에 표시됩니다. 백엔드 서비스 또는 데이터베이스에서 데이터를 얻는 것이 좋은 장소입니다.

뷰가 화면으로 완전히 전환되면 호출됩니다. 기본은 아무것도하지 않습니다

8. viewWillDisappear

이 viewWillDisappear행사는 제시된 견해 viewController가 사라지거나, 사라지거나, 가리거나 숨기려고 할 때 발생 viewController한다 이것은 네트워크 호출을 제한하거나 타이머를 무효화하거나 그에 바인딩 된 객체를 해제 할 수있는 좋은 장소입니다 viewController.

뷰가 닫히거나 닫히거나 숨겨 질 때 호출됩니다.

9. viewDidDisappear

제시된보기 viewController가 사라지거나 숨겨 지거나 숨겨 지 자마자이 이벤트가 시작될 때 누구나 처리 할 수있는 수명주기의 마지막 단계입니다 .

뷰가 닫히거나 숨겨 지거나 숨겨진 후에 호출됩니다. 기본은 아무것도하지 않습니다

이제이 메소드를 구현할 때 Applesuper 에 따라 해당 특정 메소드의 구현 을 호출해야합니다 .

UIViewController를 서브 클래 싱하는 경우 NIB를 사용하지 않더라도이 메소드의 수퍼 구현을 호출해야합니다. 편의상 기본 init 메소드가이를 수행하고이 두 메소드 인수 모두에 대해 nil을 지정합니다. 지정된 NIB에서 파일의 소유자 프록시는 뷰 콘센트가있는 뷰 컨트롤러 서브 클래스로 클래스를 설정해야합니다. 기본보기에 연결되어 있습니다. nil nib 이름으로이 메소드를 호출하면이 클래스의 -loadView메소드는 이름이 뷰 컨트롤러의 클래스와 동일한 NIB를로드하려고 시도합니다. 그러한 NIB가 실제로 존재하지 않으면 호출 -setView:하기 전에 -view호출하거나 -loadView메소드를 대체 하여보기를 프로그래밍 방식으로 설정해야합니다.

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

UPDATE는 -로 @ThomasW 코멘트 안에 지적 viewWillLayoutSubviews하고 viewDidLayoutSubviews주 화면의 파단이로드 된 경우 테이블보기 또는 콜렉션 뷰의 세포가로드 될 때 또한 예를 들어, 다른 시간에 호출됩니다.

업데이트 -@Maria가 주석 내에서 지적한 것처럼 설명 loadView이 업데이트되었습니다.


6
viewWillLayoutSubviews및 viewDidLayoutSubviews메인 뷰의 파단이로드 된 경우 테이블 뷰 또는 뷰 컬렉션의 셀이로드 된 경우에도, 예를 들어, 다른 시간에 호출된다.
— ThomasW

이 답변에는 약간의 오해가 있습니다. loadView ()는 항상 호출되며 IB에서 컨트롤러의 뷰를 만들 때 재정의해서는 안됩니다.
— Maria

@Maria 개선 할 수 있다고 생각되면 답변을 편집하십시오. 감사.
— onCompletion

기본값은 잘못된 것이 아닙니다 viewWillAppear viewDidAppear viewDidDisappear. 어느 시점에서 super를 호출해야합니다.
— Mick

47

iOS 10,11 (Swift 3.1, Swift 4.0)

에 따르면 UIViewController의 UIKit개발자,

1. loadView ()

서브 클래스가 펜촉을 사용하지 않는 경우 사용자 정의보기 계층 구조를 만들어야하는 곳입니다. 입니다. 직접 호출해서는 안됩니다.

2. loadViewIfNeeded ()

뷰 컨트롤러의 뷰가 아직 설정되지 않은 경우로드합니다.

3. viewDidLoad ()

뷰가로드 된 후 호출됩니다. 코드로 작성된 뷰 컨트롤러의 경우 -loadView 이후입니다. 펜촉에서 아카이브되지 않은 뷰 컨트롤러의 경우 뷰가 설정된 후입니다.

4. viewWillAppear (_ 애니메이션 : Bool)

뷰가 표시 될 때 호출됩니다. 기본은 아무것도하지 않습니다

5. viewWillLayoutSubviews ()

뷰 컨트롤러의 뷰의 layoutSubviews 메소드가 호출되기 직전에 호출됩니다. 서브 클래스는 필요에 따라 구현할 수 있습니다. 기본은 아무 것도하지 않습니다.

6. viewDidLayoutSubviews ()

뷰 컨트롤러의 view의 layoutSubviews 메소드가 호출 된 직후에 호출됩니다. 서브 클래스는 필요에 따라 구현할 수 있습니다. 기본은 아무 것도하지 않습니다.

7. viewDidAppear (_ 애니메이션 : Bool)

뷰가 화면으로 완전히 전환되면 호출됩니다. 기본은 아무것도하지 않습니다

8. viewWillDisappear (_ animated : Bool)

뷰가 닫히거나 닫히거나 숨겨 질 때 호출됩니다. 기본은 아무것도하지 않습니다

9. viewDidDisappear (_ 애니메이션 : Bool )

뷰가 닫히거나 숨겨 지거나 숨겨진 후에 호출됩니다. 기본은 아무것도하지 않습니다

10. viewWillTransition (크기 : CGSize, 조정자 포함 : UIViewControllerTransitionCoordinator)

뷰가 전환 중일 때 호출됩니다.

11. willMove (toParentViewController 상위 : UIViewController?)

12. didMove (toParentViewController 상위 : UIViewController?)

이 두 가지 메소드는 하위 제어기간에 전환 할 때 컨테이너 서브 클래스가 호출 할 수 있도록 공용입니다. 재정의 된 경우 재정의를 통해 수퍼를 호출해야합니다.

이 두 가지 방법 모두에서 부모 인수는 자식이 부모에서 제거 될 때 0이 아닙니다. 그렇지 않으면 새 상위 뷰 컨트롤러와 같습니다.

13. didReceiveMemoryWarning ()

부모 응용 프로그램이 메모리 경고를 받으면 호출됩니다. iOS 6.0에서는 더 이상 기본적으로보기를 지우지 않습니다.


2
실제로 실제로 스택 오버 플로우 가이 전체 스레드에서 잘못되고 불완전한 답변을 모두 제거하지는 않습니다. 메소드 호출이 진행되는 한 귀하의 답변은 완전한 것처럼 보이므로 귀하의 답변이 정확하고 그에 맞는 것으로 가정하겠습니다.
— Logicsaurus Rex

nib아래에 언급 된 바와 같이 무엇입니까 loadView?
— Petrus Theron

2
@LogicsaurusRex 동의합니다. 같은 방식으로 그 SO 마크 중복 등의 질문이나, 나는 같은 답변으로 표시 할 수 있어야한다고 생각 보호 오래된 또는 폐기
— rmp251

위의 포인트 5가 잘못되었습니다. viewWillLayoutSubviews()의 ViewController의 뷰 객체가 호출되기 전에 호출되는 layoutSubviews()방법
— williamukoh

28

iOS 6부터 새로운 다이어그램은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


1
그 뷰를 "A"라고 부릅니다. "A"가 사라지는 동안 나타나는 두 번째보기 "B"를 고려하십시오. "A.viewDidDisappear"전후에 "B.viewWillAppear"가 있습니까? 그리고 그 두 가지 순서가 바뀌는 상황이 있습니까?
— ToolmakerSteve

새로운보기의 (B) willApear가 사라지기 전에 호출됩니다. 두 번째 질문입니다. 살펴볼 시간이 필요합니다.
— Saad

21

UIViewController의 라이프 사이클을 담당하는 메소드에 집중하자 :

  • 창조:

    - (void)init

    - (void)initWithNibName:

  • 보기 작성 :

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • 뷰 상태 변경 처리 :

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • 메모리 경고 처리 :

    - (void)didReceiveMemoryWarning

  • 할당 해제

    - (void)viewDidUnload

    - (void)dealloc

UIViewController의 라이프 사이클 다이어그램

자세한 내용은 UIViewController 클래스 참조를 참조하십시오 .


19

방법 viewWillLayoutSubviews과는 viewDidLayoutSubviews다이어그램에 언급되지 않은, 그러나이는 사이라고 viewWillAppear하고 viewDidAppear. 여러 번 호출 할 수 있습니다.


또한 메인 뷰의 하위 뷰가로드 될 때 (예 : 테이블 뷰 또는 컬렉션 뷰의 셀이로드 될 때) 호출됩니다.
— ThomasW

16

Haider의 답변은 iOS 6 이전에는 정확합니다. 그러나 iOS 6부터 viewDidUnload 및 viewWillUnload는 호출되지 않습니다. 문서의 상태가 "조회수는 더 이상 메모리 부족 조건에서이 메소드가 호출되지 않도록 제거되지 않습니다."


ViewWillDisappear, ViewDidDisappear, Dispose에 중단 점을 넣으려고했습니다. 그러나 PresentViewController () 메서드로 탐색 할 때 그중 아무것도 호출되지 않았습니다. 이유가 무엇입니까?
— Sreeraj

1
링크가 작동하지 않습니다 ... 그래서 메모리가 부족한 상태에서 OS는 무엇을합니까?
— Son

디스크에 저장 하시겠습니까?
— Ian Warburton

16

오래되고 불완전한 정보가 많이 있습니다. 들어 아이폰 OS 6 새로운 전용 :

  1. loadView[ㅏ]
  2. viewDidLoad[ㅏ]
  3. viewWillAppear
  4. viewWillLayoutSubviews 한계가 확정 된 것은 처음이다
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[비]
  8. * viewDidLayoutSubviews[비]

각주 :

(A) - 수동 동안보기를 nil을 경우 didReceiveMemoryWarning, loadView그리고 viewDidLoad다시 호출됩니다. 즉 기본적으로,이다 loadView와 viewDidLoad전용 뷰 컨트롤러 인스턴스 당 한 번 호출됩니다.

(b) 추가로 0 회 이상 호출 될 수 있습니다 .


1
viewWillLayoutSubviews및 viewDidLayoutSubviews메인 뷰의 파단이로드 된 경우 테이블 뷰 또는 뷰 컬렉션의 셀이로드 된 경우에도, 예를 들어, 다른 시간에 호출된다.
— ThomasW


0

당으로 애플의 문서 - 뷰 컨트롤러와 함께 작동 - - 시작 IOS 애플 리케이션 (스위프트)를 개발보기 컨트롤러 라이프 사이클을 이해

viewDidLoad()— 뷰 컨트롤러의 컨텐츠 뷰 (뷰 계층 구조의 맨 위)가 스토리 보드에서 만들어로드 될 때 호출됩니다. …이 방법을 사용하여 뷰 컨트롤러에 필요한 추가 설정을 수행하십시오.

viewWillAppear()— 뷰 컨트롤러의 컨텐츠 뷰가 앱의 뷰 계층 구조에 추가되기 직전에 호출됩니다. 컨텐츠보기가 화면에 표시되기 전에 발생해야하는 작업을 트리거하려면이 방법을 사용하십시오.

viewDidAppear()— 뷰 컨트롤러의 컨텐츠 뷰가 앱의 뷰 계층 구조에 추가 된 직후에 호출됩니다. 데이터 가져 오기 또는 애니메이션 표시와 같이보기가 화면에 표시되는 즉시 발생해야하는 작업을 트리거하려면이 방법을 사용하십시오.

viewWillDisappear()— 뷰 컨트롤러의 컨텐츠 뷰가 앱의 뷰 계층에서 제거되기 직전에 호출됩니다. 변경 커밋 또는 첫 번째 응답자 상태 취소와 같은 정리 작업을 수행하려면이 방법을 사용하십시오.

viewDidDisappear()— 뷰 컨트롤러의 컨텐츠 뷰가 앱의 뷰 계층에서 제거 된 직후에 호출됩니다. 이 방법을 사용하여 추가 분류 활동을 수행하십시오.

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