2009-06-02 4 views
12

Tôi gặp phải một tình huống có vẻ khác. Trong đoạn mã sau, nếu tôi xóa dòng: self.navigationController = nav, chế độ xem của trình điều khiển gốc sẽ không hiển thị, gợi ý với tôi rằng addSubview có thể không thực sự giữ lại chế độ xem như được đề xuất khác. Bất kỳ ý tưởng?AddSubview của UIView có thực sự giữ nguyên chế độ xem không?

- (void)applicationDidFinishLaunching:(UIApplication *)application { 
    self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]]; 

    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.testViewController]; 

    self.navigationController = nav; //<-- if this line is removed, test view won't show up 

    [window addSubview:nav.view]; 

    [nav release]; 
} 
+0

Câu trả lời được đánh dấu của bạn không chính xác, vì những lý do tôi đã nhận xét bên dưới. –

Trả lời

24

dòng này:

[window addSubview:nav.view]; 

KHÔNG thêm một cái nhìn vào màn hình ngay lập tức. Nó được hiển thị bởi hệ điều hành trong một số vòng lặp chạy trong tương lai trên một chuỗi có thể khác nhau. Việc thực hiện thực tế chúng tôi không thể chắc chắn.

Đây là lý do tại sao Apple định nghĩa các phương thức đại biểu như viewDidAppear/viewWillAppear, nếu không chúng tôi sẽ không cần chúng như chúng ta biết chính xác khi các sự kiện này xảy ra.

Hơn nữa, thêm một chế độ xem phụ như bạn đã nói, thực sự giữ nguyên chế độ xem. Tuy nhiên, NOT vẫn giữ được bộ điều khiển chế độ xem hoặc bộ điều khiển điều hướng. Vì bộ điều khiển điều hướng S 01N giữ lại bất kỳ bộ điều khiển chế độ xem bổ sung nào, chúng tôi không phải sao lưu chúng bằng ngà voi.

Tuy nhiên, bạn tham chiếu đến bộ điều hướng điều hướng phải duy trì vượt quá phạm vi của phương pháp. hoặc tùy thuộc vào mã của bạn nó có thể được dealloc-ed hoặc có tham chiếu của nó bị mất.

Vì vậy, bạn phải giữ một tham chiếu đến bộ điều khiển chuyển hướng với một Ivar và thiết lập nó như vậy:

self.navigationController = nav; 

Vì vậy, mặc dù nav.view chứa một con trỏ đến testViewController.view, ứng dụng không có tham chiếu điều khiển điều hướng và, bằng cách mở rộng, xem. Kết quả là một màn hình trống.


Để làm điều này rõ ràng hơn rằng nó không phải là một giữ lại/phát hành vấn đề, bạn đang thực sự bị rò rỉ trong các phương pháp sau đây:

self.testViewController = [[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]]; 

Bạn cần phải autorelease để cân bằng của bạn giữ lại/phát hành bởi:

self.testViewController = [[[TestViewController alloc] initWithNibName:@"TestView" bundle: [NSBundle mainBundle]] autorelease]; 

Vì vậy, điều đó có nghĩa là chế độ xem của bạn chưa bao giờ bị xử lý bất cứ khi nào bạn chạy mã này. Điều gì còn đảm bảo với chúng tôi rằng vấn đề của bạn thực sự là một tham chiếu bị mất.

+0

Làm việc tốt Corey, thực sự thích lời giải thích bạn đã đặt ra. – Boon

+1

Không chính xác rằng _view_ sẽ được deallocated trước khi cửa sổ giữ lại nó. Nếu trường hợp đó xảy ra, bạn sẽ thấy một ngoại lệ khi cửa sổ cố truy cập đối tượng được phân phối lại. Những gì được deallocated là nav điều khiển, ngăn cản nó từ populating xem của nó với nội dung thú vị (như nav bar và root view). –

+0

Sau khi nghĩ về nó, tôi đã thêm một số thông tin bổ sung cũng giúp giải thích những gì bạn thấy. –

0

Đây không phải là câu hỏi lưu giữ/giải phóng cho tôi. Chế độ xem của bạn sẽ không hiển thị nếu bạn nhận xét ra self.navigationController = nav; vì sau đó ở dòng tiếp theo, [window addSubview:self.navigationController.view] thuộc tính self.navigationController của bạn sẽ không được đặt. Nó có thể là nil hoặc nó sẽ sụp đổ nhưng không thể nói chắc chắn mà không cần thêm mã.

+0

Tôi đã cập nhật mã trở lại mã gốc khi mọi thứ không hoạt động và tôi phải giới thiệu self.navigationController vào những thứ để giữ tham chiếu đến nav. Ngoài ra, những gì bạn thấy ở trên là tất cả các mã có và không có gì khác. – Boon

+0

Trong mục tiêu-c, ivars bắt đầu với giá trị 0. Vì vậy, self.navigationController sẽ chỉ là 0. –

2

Sự cố có thể không phải là chế độ xem không được giữ lại, đó là bộ điều khiển không được giữ lại.

Nếu không có dòng này:

self.navigationController = nav 

Không có gì được giữ lại bộ điều khiển chuyển hướng. Nó sẽ là lạ để có cái nhìn outlive bộ điều khiển.

+0

Chế độ xem không phải là "kỳ diệu" được gắn với bộ điều khiển chế độ xem. Một khung nhìn không chỉ chết vì bộ điều khiển khung nhìn của nó chết. Nếu khung nhìn đã được giữ lại ở nơi khác, nó sẽ hoàn toàn sống lâu hơn bất kỳ bộ điều khiển xem nào. –

+0

Tôi không nói điều đó sẽ không xảy ra. Tôi nói sẽ rất lạ khi một người sống lâu hơn. Đặc biệt khi khung nhìn là khung nhìn của trình điều khiển dẫn hướng, đó là một số hệ thống phân cấp khung nhìn bên trong được điều khiển bởi bộ điều khiển dẫn hướng. –

+0

Nếu bạn làm theo quy ước, bạn nói đúng. Điểm duy nhất của tôi là nó không phải là một lý do trong và của chính nó. Lý do duy nhất điều này có xu hướng đúng là vì bạn thường không phát hành bộ điều khiển chế độ xem trước khi xóa chế độ xem của nó khỏi hệ thống phân cấp chế độ xem. Nhưng không có cơ chế trong UIViewController để giữ cho bạn làm điều này, nó chỉ xuất phát từ việc thực hành quản lý bộ nhớ thích hợp. –