2010-05-19 35 views
14

Tôi không rõ ràng về các mẫu quyền sở hữu đối tượng được yêu cầu cho các trường hợp sau. Khi UIViewController của tôi trình bày một bộ điều khiển cửa sổ bật lên, một trang tính hành động, hoặc một bộ điều khiển dạng xem khác như là phương thức, tôi có cần treo một tham chiếu được giữ lại cho bộ điều khiển con đó cho đến khi nó bị loại bỏ không?Giữ lại/phát hành mẫu cho UIPopoverController, UIActionSheet, và bộ điều khiển xem phương thức?

Nói cách khác, hãy thực hiện các dòng mã sau đây có hiệu quả "chuyển quyền sở hữu" hay không?

[aPopoverController presentPopoverFromBarButtonItem:someButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO]; 

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

Ai đó có thể chỉ cho tôi tài liệu rõ ràng về chủ đề này không?

Trả lời

26

UIPopoverViewController có quản lý/sở hữu bộ nhớ hơi khác một chút. Trình bày một popover không giữ lại bộ nhớ, vì vậy bạn không thể chuyển quyền sở hữu của popviewcontroller của bạn cho đối tượng trình bày.

Để tránh rò rỉ bộ nhớ, bạn phải áp dụng UIPopoverControllerDelegate và thực hiện các phương pháp DidDismissPopOver như sau:

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { 
    [popoverController release]; 
} 

Bằng cách này, bạn có thể alloc an toàn và trình bày một PopOver:

-(void)showSearch:(id)sender { 
    SearchViewController *searchVC = [[SearchViewController alloc] init]; 
    UIPopoverController *popVC = [[UIPopoverController alloc] initWithContentViewController:searchVC]; 
    popVC.delegate = self; 
    [popVC setPopoverContentSize:CGSizeMake(320, 100)]; 
    [popVC presentPopoverFromRect:CGRectMake(200, 200, 320, 100) inView:self.view permittedArrowDirections:0 animated:YES]; 
    [searchVC release]; 
} 
+1

Hãy coi chừng, tìm kiếmVC bị rò rỉ nếu bạn làm theo cách này. Thêm một autorelease. – steipete

+0

Có, tìm kiếmVC bị rò rỉ. Thay vì một autorelease, một bản phát hành đơn giản cũng sẽ hoạt động. Thêm dòng này vào dòng cuối cùng: '[tìm kiếmVC release];' –

+1

Là tài liệu cho 'popoverControllerDidDismissPopover:' nói: _ "Bộ điều khiển bật lên không gọi phương thức này để trả lời các cuộc gọi có lập trình đến phương thức dismissPopoverAnimated: Nếu bạn bỏ qua cửa sổ bật lên theo chương trình, bạn nên thực hiện bất kỳ hành động dọn dẹp nào ngay sau khi gọi phương thức dismissPopoverAnimated: "_. Vì vậy, nếu bạn sử dụng 'dismissPopoverAnimated:', bạn cũng sẽ cần phải gọi phát hành sau đó, nếu không bạn sẽ bị rò rỉ. – ivanzoid

1

Trình bày bộ điều khiển chế độ xem vẫn giữ được UIViewController. Điều này thực sự không rõ ràng từ các tài liệu. Tuy nhiên, tôi đã kiểm tra nó bằng cách sử dụng đoạn mã sau ...

NSLog(@"BEFORE %d", [self.setupViewController retainCount]); 
[self.navigationController presentModalViewController:self.setupViewController animated:YES]; 
NSLog(@"AFTER %d", [self.setupViewController retainCount]); 

Các self.setupViewController đã được giữ lại tại địa phương, nhưng trình bày nó ra như sau:

2010-05-19 10:07:36.687 LocateMe[27716:207] BEFORE 1 
2010-05-19 10:07:36.762 LocateMe[27716:207] AFTER 3 

Vì vậy, nó có lẽ là được giữ lại trong các thuộc tính modalViewController cục bộ, cũng như trong phân cấp khung nhìn. Loại bỏ nó sẽ cân bằng chúng.

Vì vậy, dòng dưới cùng là giữ lại nó nếu bạn muốn kiểm soát trực tiếp, nhưng bạn không phải làm như vậy.

EDIT - Chỉ cần rõ ràng, mẫu chính xác là luôn giữ lại một đối tượng nếu bạn đặt mình làm đại biểu của nó. Đó là bởi vì bạn nên thiết lập các đại biểu để nil trong dealloc của bạn cho an toàn. Thực tế, mặc dù, một bộ điều khiển phương thức luôn luôn được loại bỏ trước khi bạn dealloc, do đó, nó không phải là một vấn đề. Bạn sẽ nhận thấy Apple cũng phá vỡ quy tắc này trong [UIView setAnimationDelegate:], thực tế giữ lại đại biểu bạn đã đặt.

+0

tôi sẽ cũng thêm rằng nhiều mẫu mã của Apple khởi tạo một UIViewController, trình bày nó một cách bình thường, và sau đó phát hành nó. Hãy xem ví dụ về AddMusic. – DougW

+0

Điều tương tự cũng xảy ra đối với các cửa sổ bật lên và trang tính hành động? –

+0

Có, bạn có thể kích hoạt UIAlertView và sau đó thả nó ra. Hoặc bạn có thể giữ lại nó nếu bạn muốn làm điều gì đó với nó. Dù bằng cách nào là tốt, chỉ cần chắc chắn rằng bạn cân bằng của bạn giữ lại/phát hành. – DougW

Các vấn đề liên quan