2010-05-19 60 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