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


299

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

특히, 내가 사용하는 방법을 알고 싶습니다 Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnloadDisposeA의 모노 터치의 메소드 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
viewWillLayoutSubviewsviewDidLayoutSubviews메인 뷰의 파단이로드 된 경우 테이블 뷰 또는 뷰 컬렉션의 셀이로드 된 경우에도, 예를 들어, 다른 시간에 호출된다.
ThomasW

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

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

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

47

iOS 10,11 (Swift 3.1, Swift 4.0)

에 따르면 UIViewControllerUIKit개발자,

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다시 호출됩니다. 즉 기본적으로,이다 loadViewviewDidLoad전용 뷰 컨트롤러 인스턴스 당 한 번 호출됩니다.

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


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


0

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

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

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

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

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

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

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