iPhone SDK : loadView와 viewDidLoad의 차이점은 무엇입니까?


136

iPhone 앱에서 뷰 및 뷰 컨트롤러로 작업 할 때 누구나 loadView와 viewDidLoad의 차이점을 설명 할 수 있습니까?

내 개인적인 맥락은 코드에서 모든보기를 작성한다는 것입니다. 인터페이스 빌더를 사용하지 않을 것입니다.

init 코드를 loadView에 추가 할 때 무한 스택 추적으로 끝나는 경우가 많으므로 일반적으로 viewDidLoad에서 모든 자식 뷰 건물을 수행하지만 각각이 실행될 때 나에게 분명하지 않습니다. init 코드를 넣기에 더 적합한 곳은 무엇입니까? 완벽한 것은 초기화 호출의 간단한 다이어그램입니다.

감사!

답변:


200

내가 한 일 때문에 여기에서 문제가 무엇인지 짐작할 수 있습니다.

init 코드를 loadView에 추가하면 무한 스택 추적으로 끝나는 것을 자주 발견했습니다.

-loadView에서 self.view를 읽지 마십시오. 설정 하지 않는, 그것을 얻기 를.

self.view 속성 접근 자는 뷰가 현재로드되지 않은 경우 -loadView를 호출 합니다. 무한 재귀가 있습니다.

Apple의 Pre-Interface-Builder 예제에서 설명한 것처럼 -loadView에서 프로그래밍 방식으로 뷰를 작성하는 일반적인 방법은 다음과 같습니다.

UIView *view = [[UIView alloc] init...];
...
[view addSubview:whatever];
[view addSubview:whatever2];
...
self.view = view;
[view release];

그리고 IB를 사용하지 않았다고 비난하지 않습니다. 나는 모든 Instapaper에 대해이 방법을 고수했으며 IB의 복잡성, 인터페이스 문제 및 예기치 않은 비하인드 행동을 다루는 것보다 훨씬 더 편합니다.


아아, 설명해 주셔서 감사합니다. 마침내! 나는 임시 변수를 할당 한 다음 self.view로 설정 한 다음 릴리스하는 관용구에서 멀어졌습니다. 어쨌든 어색하고 불필요한 것처럼 보였습니다. 나는 이제 그 결정이 왜 내가 지금 찾던 길로 나를 이끌 었는지 이해할 수 있습니다.
ryan.scott

나는 그런 코드를 가지고 있으며 재귀는 없다. 왜? -(void) loadView { // Frame for Hypnosis view CGRect frame = [[UIScreen mainScreen] bounds]; // Create a Hipnosis view v = [[HypnosisView alloc] initWithFrame:frame]; self.view = v;
user2054339

44

loadViewUIViewController실제로 뷰를로드하고 view속성에 할당 하는 방법입니다 . UIViewController프로그래밍 방식으로 view속성을 설정하려는 경우 하위 클래스 가 재정의 하는 위치이기도합니다 .

viewDidLoad뷰가로드되면 호출되는 메소드입니다. loadView가 호출 된 후 호출됩니다. 뷰가 일단로드되면 추가 초기 설정을 수행하는 코드를 무시하고 삽입 할 수있는 위치입니다.


14
viewDidLoad()

NIB에서보기를로드 할 때 사용되며 실행 후 사용자 정의를 수행하려고합니다.

LoadView()

프로그래밍 방식으로보기를 작성하려고 할 때 사용됩니다 (인터페이스 빌더 사용하지 않고).


이것은 약간의 문제가있을 수 있습니다. 뷰 컨트롤러가 NIB 파일과 연결되지 않았을 때 테스트했습니다. viewDidLoad는 여전히 호출됩니다
ruandao

11

NilObject가 말한 것을 보여주기 위해 몇 가지 코드 예제를 추가하십시오.

- (void)loadView
{
    // create and configure the table view
    myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStyleGrouped];   
    myTableView.delegate = self;
    myTableView.dataSource = self;
    myTableView.scrollEnabled = NO;
    self.view = myTableView;

    self.view.autoresizesSubviews = YES;
}

- (void)viewDidLoad 
{
  self.title = @"Create group";

  // Right menu bar button is to Save
  UIBarButtonItem *saveButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)];
  self.navigationItem.rightBarButtonItem = saveButtonItem;
  [saveButtonItem release];
}

4
그래서 둘 사이에서 loadView가 컨트롤러 self.view의 alloc / init을 수행 해야하는 곳이라고 말하고 자식 뷰는 viewDidLoad (또는 그 이후)에서 처리되어야한다고 말하는 것이 정확합니까?
ryan.scott

2

self.view를 읽을 때 무한 루프가 발생하지 않도록하려면 뷰를로드 할 때 클래스의 수퍼 구현을 호출하십시오. 슈퍼 구현은 새로운 UIView를 할당합니다.

- (void) loadView {
[super loadview];

// init code here...

[self.view addSubView:mySubview1]; //etc..

}

6
애플의 문서에 전화를해서는 안된다고 맹세 할 수있다 [super loadView];. 그것은 예제에서 모순되었지만 문서가 올바르게 말했다고 생각합니다 (시간이 지남에 따라 예제에서 많은 버그를 발견했습니다). [super loadView]그러나 UITableViewController 등에 필요합니다. 하나! 로드 후 설정 (예 : 추가 서브 뷰 추가)은 viewDidLoad에서 수행해야합니다.
이반 부카

지금까지 부작용없이 [super loadView]를 호출했습니다. self.view를 자신이 만든 것으로 설정하려는 경우에 해당 될 수 있습니다.
futureelite7

loadView 내부에서 [super loadView]를 호출하면 기본 이름으로 사용 가능한 경우 펜촉에서 뷰를로드하려고 시도합니다. 따라서 조심해야합니다.
Ian1971

[super loadView]를 호출하면 super loadView 메소드에서 self.view를 초기화합니다.
Alex Nazarsky

1

loadView를 사용하는 가장 쉬운 방법은 UIViewController의 하위 클래스 인 MyBaseViewController와 같은 일부 유형의 기본 뷰 컨트롤러를 만드는 것입니다. loadView 메소드는 다음과 같이 뷰를 작성합니다.

-(void) loadView {
    if ([self viewFromNib]) {
        self.view = [self viewFromNib];
    } else {
        self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    }
    self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self.view.backgroundColor = [UIColor whiteColor];
}

그리고 뷰 컨트롤러를 만들어야 할 때 MyBaseViewController의 서브 클래스를 사용하고 loadView 컨트롤러에서는 다음과 같이 [super loadView]라고 부릅니다.

//sucblass loadView
-(void) loadView {
    [super loadView];

    //rest of code like this..
    UILabel *myLabel = [[UILabel alloc] initWithFrame:myFrame];
    [self.view addSubview:myLabel];
    [myLabel release];
}

1

loadView()컨트롤러가를 생성하라는 메시지가 표시되면 호출됩니다 self.view. 당신은처럼 혼자서 할 수 있습니다

self.view = [UIView alloc] init...];

또는 컨트롤러의 부모 UIController 클래스에는 이미 -loadView()self.view를 빈보기로 초기화 하는 메소드 이름 이 있습니다. 그럼 당신은 전화 할 수 있습니다

[super loadView];

상속을 장려하기 때문에 두 번째 방법을 권장합니다. 뷰 컨트롤러가 UIViewController에서 직접 상속되지 않은 경우에만 해당됩니다.


0

viewDidLoad에 대한 Apple의 정의는 컨트롤러의 뷰가 메모리에로드 된 후에 호출된다고 언급했습니다. 간단히 말해서로드하는 첫 번째 방법입니다.

이 방법이 어떤 조건에서 완전히 활용 될 것이라고 생각하십니까? 대답은 기본적으로 앱이 먼저로드되기를 원하는 것입니다. 예를 들어 흰색 대신 다른 배경색을 원할 경우 파란색을 선택할 수 있습니다.

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