2010-05-19 62 views
14

對於以下實例所需的對象所有權模式,我有點不清楚。當我的UIViewController將一個彈出窗口控制器,一個操作表或另一個視圖控制器顯示爲模態時,我是否需要掛起對該子控制器的保留引用,直到它被解除爲止?UIPopoverController,UIActionSheet和模態視圖控制器的保留/釋放模式?

換句話說,下面的代碼行有效地「轉移」了所有權嗎?

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

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO]; 

[aViewController presentModalViewController:someOtherViewController animated:YES]; 

有人可以指出我對這個問題的明確文件嗎?

回答

26

UIPopoverViewController有一個不同的內存管理/擁有。目前彈出窗口不保留內存,因此您不能將popviewcontroller的所有權轉移給展示對象。

爲了避免內存泄漏,必須採取UIPopoverControllerDelegate和實施DidDismissPopOver方法如下:

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

這樣,您就可以安全alloc和呈現酥料餅:

-(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

請注意,如果你這樣做,searchVC就會漏水。添加一個autorelease。 – steipete 2011-04-15 19:52:55

+0

是的,searchVC被泄露。而不是一個autorelease,一個簡單的版本也將工作。將此添加到最後一行: '[searchVC release];' – 2011-04-18 21:27:13

+1

作爲'popoverControllerDidDismissPopover:'的文檔說: _「popover控制器不響應編程調用dismissPopoverAnimated:方法調用此方法。通過編程方式關閉彈出窗口,您應該在調用dismissPopoverAnimated:方法後立即執行任何清理操作。「_。 所以如果你使用'dismissPopoverAnimated:'你還需要在它後面調用釋放,否則你會得到泄漏。 – ivanzoid 2011-05-31 10:01:40

1

呈現模態視圖控制器保留UIViewController。這實際上並不清楚從文檔。不過,我測試了它使用下面的代碼...

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

的self.setupViewController已經在本地保留,但呈現它的輸出如下:

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

所以它可能被保留在本地modalViewController屬性以及視圖層次結構中。解僱它會平衡這些。

所以底線是,保留它,如果你想直接控制它,但你不必。

編輯 - 就是要清楚,正確模式是,如果您將自己設置爲其代表,則始終保留一個對象。那是因爲你應該將代理設置爲零,以保證安全。實際上,一個模態控制器總是會在你釋放之前被解僱,所以這不是問題。您會注意到Apple在[UIView setAnimationDelegate:]中也違反了這個規則,它實際上保留了您設置的委託。

+0

我會還要添加很多Apple的示例代碼初始化一個UIViewController,以模態方式呈現它,然後釋放它。查看AddMusic示例。 – DougW 2010-05-19 17:14:23

+0

同樣適用於彈出和動作表嗎? – 2010-06-01 00:13:59

+0

是的,你可以觸發UIAlertView,然後釋放它。或者如果你想對它做點什麼,你可以保留它。無論哪種方式都很好,只要確保你平衡你的保留/版本。 – DougW 2010-06-01 19:10:51