ProgramingTip

UIViewController 탄생의 과정은 무엇입니까 (어떤 방법이 뒤 따르는가)?

bestdevel 2020. 12. 13. 10:22
반응형

UIViewController 탄생의 과정은 무엇입니까 (어떤 방법이 뒤 따르는가)?


같은 오버라이드 (재정의)하는 많은 방법이있다 initWithNibname:, awakeFromNib, loadView, viewDidLoad, viewDidAppear:, layoutSubviews, 난 그냥 순서라는이 방법을 얻을 수있는 결정할 수 없습니다가 .

나는 그들 중 하나를 "마음으로"무시합니다.

상세한 설명이 있습니까?


Cocoa 뷰와 viewController 관리 에 대한 배후에서 많은 일이 진행되고 있습니다.

1. viewController 객체

가장 기본적인 viewController는 일반적인 클래스입니다. 초기화 된 항목이 처음 할당 된 물건보기 개체가 없습니다. 뷰는 필요한 경우에만 인스턴스화됩니다. 따라서 뷰를 고려하지 않고 viewController의 수명주기는 다른 객체와 동일합니다.

UIViewController * myVC = [[UIViewController alloc] initWith...];
...
[myVC release];

viewController에 대해 지정된 이니셜 라이저는 입니다. 펜촉을 지정하면 viewController는 해당 펜촉에서 뷰를 자동으로로드하고 정의한 IBOutlet을 강조 할 수 있습니다 (자세한 내용은 아래 참조).-initWithNibname:bundle:

2. 뷰로드 및 언로드

viewController는 필요에 따라 뷰를로드합니다. 이는 일반적으로 -view메서드가 호출 될 때 발생하며 UI를 초기화하는 방법에 따라 프로그램에서 보관 수 있습니다. 뷰는 UI 관리 방법에 따라 프로그램 수명 동안 여러 번 파괴되고 다시로드 될 수도 있습니다. viewController가 뷰가 필요하지만 아직로드되지 않았는지 확인하면 -loadView메서드가 호출됩니다. 기본 메시지 흐름은 다음과 가변합니다.

view
  loadView
  viewDidLoad

당신이 무시하면 -view방법을, -loadView그리고 viewDidLoad자동으로 호출되지 않습니다. 당신이 오버라이드 (재정의)하는 경우 -loadView,은 당신 해야 우리한다 의의 ViewController 설정의 view속성을. 확장에 대한 다음 호출 -view이로 드 프로세스를 다시 트리거합니다.

보기는 숙박 시설 view로 설정하여 프로그램의 수명 동안 언로드 할 수 있습니다 nil. 의 기본 구현은 -didReceiveMemoryWarning뷰에 수퍼 뷰가없는 한 (즉, 현재 활성 뷰 계층 구조의 일부가 아닌 경우)이 작업을 자동으로 수행합니다. 메시지 흐름은 다음과 가변됩니다.

view = nil
   viewDidUnload

2a. 프로그래밍 방식으로보기로드

을 재정의 선택하면 원하는 방식으로 -loadView보기, 하위보기, 다른 viewController 및 개체 연결을 만들 수 있습니다. 물론 당신이 생성하는 것과 관련하여 메모리를 담당한다는 것을 의미합니다. 클래스가 재정의하는 경우 하위 에 대해 -loadView사용하여 초기화해야합니다 .nilnibNamebundle

2b. 펜촉에서보기로드

nib 파일을 사용하는 경우의 기본 구현은 해당 nib 파일을 자동으로 사용하는 -loadView파일 인스턴스화하고 이들 사이의 연결을 추가하고 메모리 관리를 처리합니다.

Nib 파일은 뒤에서 많은 일이 발생하기 때문에 상황이 조금 더 까다로워에서 처리합니다. -awakeFromNib메서드는 펜촉이로드 될 파일 때 인스턴스화되는 모든 개체에 대해 호출되며 펜촉 파일의 다른 개체가 호출 될 때 완전히로드된다는 보장은 없습니다 .

3.보기 표시

-viewWillAppear:, -viewDidAppear:, -viewWillDisappear:-viewDidDisappear:보기가 특히 하나 개의보기에서 다른 애니메이션 transistions 동안 표시되거나 화면에 숨겨진되는 경우 에만 호출됩니다 . 여러 번 호출 될 수 있습니다.

4. 레이아웃보기

-layoutSubviews메서드는의 일부 아닙니다UIViewController. UIView경계가 변경 될 때 객체에 대해 호출 됩니다. UIView프로그램에서 사용자 지정 하위 클래스 를 사용하는 경우 Cocoa의 기본 자동 크기 조정 방법에 의존하는 대신이 방법을 사용하여 사용자 지정 하위보기 레이아웃을 수행 할 수 있습니다.

5. 종합하기

이러한 프로세스가 발생하는 방법은 여러 가지가 있습니다. 타임 라인은 다음과 같을 수 있습니다.

-[viewController initWithNibname:Bundle:]
-[viewController awakeFromNib]
-[viewController loadView]
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController viewWillAppear]     // user navigated back
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController setView:nil]        // memory warning, perhaps
-[viewController viewDidUnload]
...
-[viewController loadView]           // user navigated back
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...

나는 최근에 다시 방문하고 테스트 프로젝트를 만들었습니다 : https://github.com/Janek2004/ViewControllerTest

iOS 시뮬레이터에서 프로젝트를 실행하여 UIViewController 하위 클래스 메서드의 실행 순서를 확인합니다. 스토리 보드 대신 Nib 파일을 사용하거나 프로그래밍 방식으로 뷰 컨트롤러를로드 할 때마다 순서가 다를 수 있습니다.

  1. -[ViewController initWithCoder :] nib 또는 스토리 보드에서 데이터 보관 취소
  2. -[ViewController awakeFromNib] Interface Builder 아카이브 또는 nib 파일에서로드 된 후 서비스를 위해 수신자를 준비합니다.
  3. -[ViewController loadView] 이 메서드를 직접 호출해서는 안됩니다. 뷰 컨트롤러는 뷰 속성이 요청되었지만 현재는 nil 일 때이 메서드를 호출합니다. 이 메서드는 뷰를로드하거나 생성하고 뷰 속성에 할당합니다.
  4. -[ViewController viewDidLoad] 이 메서드는 뷰 컨트롤러가 뷰 계층 구조를 메모리에로드 한 후에 호출됩니다.
  5. -[ViewController viewWillAppear :] 이 메소드는 수신자의 뷰가 뷰 계층 구조에 추가되기 전과 뷰를 표시하기 위해 애니메이션이 구성되기 전에 호출됩니다.
  6. -[ViewController viewWillLayoutSubviews] 뷰 컨트롤러에게 뷰가 하위 뷰를 레이아웃하려고한다는 것을 알리기 위해 호출됩니다. 뷰의 경계가 변경되면 뷰는 하위 뷰의 위치를 ​​조정합니다. 뷰 컨트롤러는 뷰가 하위 뷰를 배치하기 전에이 메서드를 재정 의하여 변경할 수 있습니다.
  7. -[ViewController viewDidLayoutSubviews] 뷰 컨트롤러에 뷰가 서브 뷰를 방금 배치했음을 알리기 위해 호출됩니다. 뷰 컨트롤러의 뷰에 대한 경계가 변경되면 뷰는 하위 뷰의 위치를 ​​조정 한 다음 시스템이이 메서드를 호출합니다. 그러나이 메서드가 호출 되어도 뷰의 하위 뷰의 개별 레이아웃이 조정되었음을 나타내는 것은 아닙니다. 각 하위보기는 자체 레이아웃을 조정해야합니다.
  8. -[ViewController viewDidAppear :] 해당 뷰가 뷰 계층 구조에 추가되었음을 뷰 컨트롤러에 알립니다. 이 메서드를 재정 의하여보기 표시와 관련된 추가 작업을 수행 할 수 있습니다.

  9. -[ViewController viewWillDisappear :] 해당 뷰가 뷰 계층에서 제거 될 예정임을 뷰 컨트롤러에 알립니다.이 메서드는 뷰 계층에서 제거되는 뷰에 대한 응답으로 호출됩니다. 이 메서드는보기가 실제로 제거되기 전과 애니메이션이 구성되기 전에 호출됩니다. 뷰가 뷰 계층에 추가되었음을 뷰 컨트롤러에 알립니다. 이 메서드를 재정 의하여보기 표시와 관련된 추가 작업을 수행 할 수 있습니다.

  10. -[ViewController viewDidDisappear :] 해당 뷰가 뷰 계층 구조에서 제거되었음을 뷰 컨트롤러에 알립니다.

프로세스의 또 다른 중요한 순간은 모든 하위보기에서 layoutSubviews가 호출되는 경우입니다. 이 시점에서 스토리 보드에 구성된 제약 조건이 적용되었습니다. 제한된 좌표를 기반으로 뷰의 하위 뷰를 조정해야하는 경우 layoutSubviews에서 조정해야합니다. viewDidLayoutSubviews에서 수행하면 해당 하위 뷰에 아직 제약 조건이 적용되지 않았기 때문에 너무 빠를 것입니다 (문서에 "각 하위 뷰가 자체 레이아웃을 조정해야합니다"라고 나와 있기 때문입니다.). viewDidAppear에서 수행하면 사용자가 하위 뷰가 좌표를 변경하는 것을 볼 수 있으므로 분명히 너무 늦을 것입니다. 따라서 프로세스의 다른 중요한 단계는 다음과 같습니다.

-viewController viewWillAppear
-viewController viewWillLayoutSubviews
-viewController viewDidLayoutSubviews
---> viewController.[any subview] layoutSubviews
-viewController viewDidAppear  

Apple UIViewController 문서에서 :

UIViewController의 새 하위 클래스를 정의 할 때 컨트롤러에서 관리 할 뷰를 지정해야합니다. 이러한 뷰를 지정하는 두 가지 상호 배타적 인 방법이 있습니다. 수동으로 또는 nib 파일을 사용하는 것입니다. 뷰를 수동으로 지정하는 경우 loadView 메서드를 구현하고이를 사용하여 뷰 속성에 루트 뷰 개체를 할당해야합니다. nib 파일을 사용하여 뷰를 지정하는 경우 loadView를 재정의해서는 안되지만 대신 Interface Builder에서 nib 파일을 생성 한 다음 initWithNibName : bundle : 메소드를 사용하여 뷰 컨트롤러 객체를 초기화해야합니다. nib 파일을 사용하여 뷰를 생성하는 것은 종종 더 간단합니다. Interface Builder 애플리케이션을 사용하여 뷰를 그래픽으로 생성하고 구성 할 수 있기 때문입니다 (프로그래밍 방식이 아닌). 두 기술 모두 최종 결과가 동일하지만

내 머리 위에서 :

  1. initWithNibname
  2. loadView (수동으로로드)
  3. viewDidiLoad
  4. viewDidAppear

layoutSubview가 들어가는 위치에 대한 단서가 없습니다.


일반적으로 앱 시작 대리자를 포함하여 이러한 모든 대리자에 NSLog (또는 중단 점)를 넣고 디버거의 순서를 따라이 질문을 해결합니다.


-이것은보기 전용과 관련이 있습니다.
-viewWillAppear :
-viewDidAppear : 
-viewWillDisappear : 및 
-viewDidDisappear : 

보기가 표시 될 때만 호출됩니다.

-viewController viewDidLoad
-viewController viewWillAppear
-viewController viewDidAppear

다른 방법

-viewController viewDidDisappear
-viewController viewWillDisappear 
-viewController viewDidUnload

그의 훌륭한 설명에 대해 e. James에게 감사드립니다. 아직 게시물에 대해 댓글을 달 수는 없지만 빠른 시각적 설명 은 View Controller 프로그래밍 가이드 의이 흐름도를 참조하십시오 . 그리고 이것이 주제에서 벗어난 것을 알고 있지만 앱 실행 순서그래프 는 iOS 애플리케이션 프로그래밍 가이드를 참조하십시오.

참고 URL : https://stackoverflow.com/questions/5107604/what-is-the-process-of-a-uiviewcontroller-birth-which-method-follows-which

반응형