【问题标题】:iPhone memory management question (adding a subview to a view in a for statement)iPhone内存管理问题(在for语句的视图中添加子视图)
【发布时间】:2010-10-14 20:47:47
【问题描述】:

我需要向视图添加更多视图以处理多个网址和标签上的点击。我尝试在 for 语句中做到这一点。我的代码是这样的:

// we have a UITabbarViewController for holding amongs other the parentViewController
UITabBarController *tabbedViewController = [[UITabBarController alloc] init];

// create the parentViewController
ParentViewController *parentViewController = [[ParentViewController alloc] initWithNibName:@"parentViewController" bundle:nil];
[parentViewController.view setNeedsDisplay];

// add parentViewController into tabbedViewController
tabbedPlayerViewController.viewControllers = [NSArray arrayWithObjects: ... parentViewController, nil];

// All the things are inside a UINavigationController
// push the view
[self.navigationController pushViewController:tabbedViewController animated:YES];

// setting up  the views individually...
// not listed here



for (NSDictionary *url in urls) {

        // init my controller with a nib file 
        UIViewController *webadressViewController = [[WebadressViewController alloc] initWithNibName:@"WebadressViewController" bundle:nil]; 

        // position the view ...
        // ... not listed here

        // add webaddress to parent view
        [parentViewController.view addSubview: webaddressViewController.view];

}

[parentViewController release];
[tabbedViewController release];

我想我可能有一些内存管理问题,因为 webaddressViewController 有 1 作为保留计数,所以它需要在我的代码中的某个地方释放。但是如果我在 for 块中释放它,所有子视图都会消失。

我的问题是如何释放这些对象?

(我看到的问题如下: 当我在 parentViewController 上调用 addSubview 时,它将拥有 webaddressViewController.view 但不拥有 webaddressController 本身。因此,如果我释放 webaddressViewController,它的视图也会消失。)

【问题讨论】:

    标签: iphone objective-c memory-management view


    【解决方案1】:

    您正在为每个 url 创建一个 webAdressViewController,但您并没有保留这些视图控制器,以便以后可以释放它们。如果你想这样编码,你还需要保留一个 webAdressViewControllers 数组作为该代码所属的任何对象的属性 - 然后在其 dealloc 方法中释放它们。

    但我想知道您为什么首先要创建 webAdressViewControllers?除了创建视图的代码之外,您在 webAdressViewController 类中是否有任何代码? (如果你现在说的是释放控制器,我怀疑不是。)如果你以后不需要控制器,为什么不直接创建视图,然后将它们添加为子视图并释放它们?这将使您免于保留大量不需要的视图控制器。

    您还需要将选项卡式视图控制器保留为属性,并在 dealloc 中释放它。

    parentViewController 有两个保留计数 - 一次用于分配初始化,两次用于添加到数组中。如果您不需要自己再次直接访问此控制器(即,如果选项卡式控制器完成了您需要的所有视图 cmanagement),那么您应该释放它一次。

    【讨论】:

    • 亲爱的简,谢谢你的回答。这是正确的解决方案。
    【解决方案2】:

    使用自动释放池,它会在您不再需要时释放您分配的对象。

    UIViewController *webadressViewController = [[[WebadressViewController alloc] initWithNibName:@"WebadressViewController" bundle:nil] autorelease];
    

    或者,在循环的最后一行添加release语句(推荐):

    [webaddressViewController release];
    

    如果你有一个紧密的循环,就像你在这里一样,如果你使用传统的分配/释放模式,效率会更高。

    如果您保留代码原样,则会发生内存泄漏。

    【讨论】:

    • 我都试过了,但是最近的工作:-(如果我在循环中释放它,视图将不会出现。这是我的问题。
    • 我认为您需要发布更多代码。您按照描述编写的代码存在内存泄漏。罗杰和我都在说同样的话。你能在循环之前、中间和之后发布这些行吗?
    • 在您的 nib 中,文件的所有者是否设置为正确的对象类型? tabbedPlayerViewController 是错字吗?你的意思是 tabbedViewController 吗?我认为唯一的问题是 parentViewController 是否过早释放。如果是这样,那么所有子视图也是如此。
    【解决方案3】:

    您应该在发送addSubView 消息后立即释放循环内的每个视图。 parentViewController.view 将保留视图并将其作为其dealloc 的一部分发布。

    如果您在此之前释放它们,视图将被释放。

    相反,您应该保留您的 parentViewController。这是拥有您创建的视图的视图控制器。当您释放它时,它会释放您添加所有其他视图的视图 - 依次释放它们。

    当 parentView 控制器被用户关闭时,您释放它。

    【讨论】:

    • 是的,这就是我学到的。但是如果我在循环的最后一行释放 webadressViewController,就不会出现任何视图。
    • 我认为您需要向我们展示更多代码。你是如何显示 parentView 的?
    【解决方案4】:

    虽然可能与手头的问题无关,但请注意 UINavigationController 不支持推送 UITabBarController。请参阅this SO question(和答案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      相关资源
      最近更新 更多