【问题标题】:Retain/release pattern for UIPopoverController, UIActionSheet, and modal view controllers?UIPopoverController、UIActionSheet 和模态视图控制器的保留/释放模式?
【发布时间】:2011-02-21 12:02:04
【问题描述】:

我对以下实例所需的对象所有权模式有些不清楚。当我的 UIViewController 将弹出框控制器、操作表或另一个视图控制器呈现为模态时,我是否需要挂起对该子控制器的保留引用,直到它被解除?

换句话说,以下代码行是否有效地“转移”了所有权?

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

[anActionSheet showFromBarButtonItem:someButtonItem animated:NO];

[aViewController presentModalViewController:someOtherViewController animated:YES];

有人可以指出有关此主题的明确文档吗?

【问题讨论】:

    标签: iphone uiviewcontroller uiactionsheet uipopovercontroller


    【解决方案1】:

    UIPopoverViewController 的内存管理/拥有略有不同。呈现弹出框不会保留内存,因此您无法将 popviewcontroller 的所有权转移给呈现对象。

    为了避免内存泄漏,你必须采用 UIPopoverControllerDelegate 并实现 DidDismissPopOver 方法如下:

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

    这样,您可以安全地分配并呈现一个 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];
    }
    

    【讨论】:

    • 当心,如果你这样做,searchVC 会泄漏。添加自动释放。
    • 是的,searchVC 被泄露了。除了自动释放,简单的释放也可以工作。将此添加到最后一行:[searchVC release];
    • 正如popoverControllerDidDismissPopover: 的文档所说:“弹出框控制器不会调用此方法来响应对dismissPopoverAnimated: 方法的编程调用。如果您以编程方式关闭弹出框,您应该执行任何在调用 dismissPopoverAnimated: 方法后立即清除操作。”。所以如果你使用dismissPopoverAnimated:,你还需要在它之后调用release,否则你会得到一个泄漏。
    • 终于接受了这个答案。感谢大家的贡献。令人讨厌的是,此控件的行为与名义上相似的交互模式不同。
    【解决方案2】:

    呈现模态视图控制器会保留 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 属性以及视图层次结构中。解雇它会平衡这些。

    所以底线是,如果您想直接控制它,请保留它,但您不必这样做。

    编辑 - 明确一点,正确模式是如果您将自己设置为对象,则始终保留对象。那是因为为了安全起见,您应该在您的 dealloc 中将委托设置为 nil。但实际上,模态控制器总是会在您解除分配之前被解除,所以这不是问题。您会注意到 Apple 在 [UIView setAnimationDelegate:] 中也违反了此规则,它实际上保留了您设置的委托。

    【讨论】:

    • 我还要补充一点,Apple 的大部分示例代码都会初始化 UIViewController,以模态方式呈现它,然后释放它。查看 AddMusic 示例。
    • 弹出框和操作表也一样吗?
    • 是的,你可以触发 UIAlertView 然后释放它。或者,如果你想对它做点什么,你可以保留它。无论哪种方式都可以,只要确保平衡保留/释放即可。
    • 这是不正确的——如果你分配了一个自动释放的弹出框并呈现它,你会崩溃,因为它在呈现后会被释放。这意味着您必须保留对弹出框的引用,直到它被解除,除非您可以泄漏它。这似乎完全是蹩脚的,并且与其他东西不一致,但你就是这样。
    • 是正确的,并且警报视图不会泄漏。去阅读文档 (bit.ly/b25V5U)。 Apple 反复演示了用于模态窗口和警报视图的 alloc-present-release 模式。
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多