iPhone SDK: sự khác biệt giữa loadView và viewDidLoad là gì?


136

Khi làm việc với chế độ xem và xem bộ điều khiển trong ứng dụng iPhone, bất kỳ ai cũng có thể giải thích sự khác biệt giữa loadView và viewDidLoad?

Bối cảnh cá nhân của tôi, là tôi xây dựng tất cả các quan điểm của mình từ mã, tôi không và sẽ không sử dụng Trình tạo giao diện, điều đó sẽ tạo ra sự khác biệt.

Tôi đã thấy rằng thường khi tôi thêm mã init vào loadView, tôi kết thúc bằng một dấu vết ngăn xếp vô hạn, vì vậy tôi thường thực hiện tất cả việc xây dựng chế độ xem con của mình trong viewDidLoad ... nhưng nó thực sự không rõ ràng với tôi khi mỗi lần được thực thi và nơi thích hợp hơn để đặt mã init. Những gì sẽ là hoàn hảo, là một sơ đồ đơn giản của các cuộc gọi khởi tạo.

Cảm ơn!

Câu trả lời:


200

Tôi có thể đoán những gì có thể là vấn đề ở đây, bởi vì tôi đã làm nó:

Tôi đã thấy rằng thường khi tôi thêm mã init vào loadView, tôi kết thúc bằng dấu vết ngăn xếp vô hạn

Đừng đọc self.view in -loadView. Chỉ đặt nó, không nhận được nó.

Trình truy cập thuộc tính self.view gọi -loadView nếu chế độ xem hiện không được tải. Có đệ quy vô hạn của bạn.

Cách thông thường để xây dựng chế độ xem theo chương trình trong -loadView, như được minh họa trong các ví dụ về Trình tạo giao diện trước của Apple, giống như sau:

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

Và tôi không trách bạn đã không sử dụng IB. Tôi đã bị mắc kẹt với phương pháp này cho tất cả Instapaper và thấy mình thoải mái hơn nhiều so với việc giải quyết các vấn đề phức tạp, giao diện của IB và hành vi hậu trường bất ngờ.


ahhhh, cảm ơn bạn đã giải thích, cuối cùng! Tôi đã tránh xa thành ngữ phân bổ một biến tạm thời, sau đó đặt thành self.view, sau đó phát hành ... có vẻ như hơi khó xử, không cần thiết. Bây giờ tôi có thể hiểu tại sao quyết định đó sẽ đưa tôi xuống con đường mà bây giờ tôi thấy mình.
ryan.scott

Tôi có mã như vậy và không có đệ quy. tại sao? -(void) loadView { // Frame for Hypnosis view CGRect frame = [[UIScreen mainScreen] bounds]; // Create a Hipnosis view v = [[HypnosisView alloc] initWithFrame:frame]; self.view = v;
dùng2054339

44

loadViewlà phương thức trong UIViewControllerđó thực sự sẽ tải lên khung nhìn và gán nó cho thuộc viewtính. Đây cũng là vị trí mà một lớp con UIViewControllersẽ ghi đè nếu bạn muốn thiết lập thuộc viewtính theo chương trình .

viewDidLoadlà phương thức được gọi khi chế độ xem được tải. Điều này được gọi sau khi loadView được gọi. Đó là nơi bạn có thể ghi đè và chèn mã để thiết lập ban đầu thêm cho chế độ xem sau khi được tải.


14
viewDidLoad()

sẽ được sử dụng khi bạn tải chế độ xem của mình từ NIB và muốn thực hiện bất kỳ tùy chỉnh nào sau khi khởi chạy

LoadView()

sẽ được sử dụng khi bạn muốn tạo chế độ xem theo chương trình (không sử dụng Trình tạo giao diện)


Điều này có thể có một số vấn đề, tôi đã kiểm tra khi trình điều khiển xem của tôi không được liên kết với tệp NIB, viewDidLoad vẫn được gọi
ruandao

11

Chỉ cần thêm một số ví dụ mã để chứng minh những gì NilObject đã nói:

- (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
vì vậy, giữa hai bạn, có chính xác không khi nói rằng loadView là nơi tôi nên thực hiện cấp phát / init cho chế độ tự điều khiển của mình và các chế độ xem con nên được xử lý trong viewDidLoad (hoặc mới hơn)?
ryan.scott

2

Để ngăn vòng lặp vô hạn xảy ra khi bạn đọc self.view, hãy gọi siêu triển khai của lớp khi bạn tải chế độ xem. Việc triển khai siêu sẽ phân bổ một UIView mới cho bạn.

- (void) loadView {
[super loadview];

// init code here...

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

}

6
Tôi có thể thề tài liệu của Apple nói rằng bạn không nên gọi [super loadView];. Điều đó đã được mâu thuẫn trong các ví dụ, nhưng tôi nghĩ rằng các tài liệu đã nói chính xác (tôi đã tìm thấy nhiều lỗi trong các ví dụ theo thời gian). [super loadView]là cần thiết cho UITableViewControll, v.v. Tuy nhiên! Bất kỳ thiết lập sau tải nào (ví dụ: thêm các cuộc phỏng vấn bổ sung) nên được thực hiện trong viewDidLoad.
Ivan Vučica

Tôi đã gọi [super loadView] mà không có bất kỳ tác dụng phụ nào cho đến nay. Nó có thể đúng nếu bạn có ý định tự đặt mình. Xem xét một vài thứ bạn tự làm.
Futureelite7

Nếu bạn gọi [super loadView] bên trong loadView thì nó sẽ cố tải chế độ xem từ ngòi nếu có sẵn với tên mặc định. Vì vậy bạn cần cẩn thận.
Ian1971

Và nếu bạn gọi [super loadView], bạn khởi tạo self.view theo phương thức super loadView
Alex Nazarsky

1

Cách dễ nhất để sử dụng loadView là tạo một số loại trình điều khiển khung nhìn cơ sở, như MyBaseViewControll là lớp con của UIViewControll. Trong phương thức loadView, hãy tạo chế độ xem theo cách này:

-(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];
}

Và khi bạn cần tạo một số trình điều khiển xem, bạn chỉ cần sử dụng lớp con của MyBaseViewControll và trong trình điều khiển loadView của nó, bạn chỉ cần gọi [super loadView] như thế này

//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()được gọi khi bộ điều khiển của bạn được yêu cầu tạo ra nó self.view. Bạn có thể làm điều đó một mình

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

Hoặc lớp UIContler cha mẹ của bộ điều khiển của bạn đã có một tên phương thức -loadView()khởi tạo self.view của bạn thành dạng xem trống. Sau đó bạn có thể gọi

[super loadView];

Tôi thực sự khuyên bạn nên tiếp cận thứ hai vì nó khuyến khích sự kế thừa. Chỉ khi bộ điều khiển xem của bạn không được kế thừa trực tiếp từ UIViewContoder.


0

Định nghĩa do Apple đưa ra trên viewDidLoad đã đề cập rằng nó được gọi sau khi chế độ xem của bộ điều khiển được tải vào bộ nhớ. Nói một cách đơn giản, đây là phương pháp đầu tiên sẽ tải.

Bạn có thể nghĩ trong điều kiện nào phương pháp này sẽ được sử dụng đầy đủ? Câu trả lời là, về cơ bản, bất cứ điều gì bạn muốn ứng dụng tải đầu tiên. Chẳng hạn, bạn có thể muốn một màu nền khác, thay vì màu trắng, có lẽ bạn có thể chọn màu xanh lam.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.