【问题标题】:Releasing detail view controller causes memory problems释放细节视图控制器导致内存问题
【发布时间】:2011-01-26 15:42:21
【问题描述】:

我有一个基于拆分视图控制器的应用程序。在详细视图控制器中,将其称为 FirstViewController,当用户按下按钮时,我会使用新的视图控制器更新视图控制器,称为 SecondViewContorller,如下所示:

- (void) buttonPressed:(id)sender {
     UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

     SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
     ...
     detailViewController = secondVC;

     MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
     UINavigationController *nav = (UINavigationController *)[delegate.splitViewController.viewControllers objectAtIndex: 0];
     NSArray *viewControllers = [NSArray arrayWithObjects:nav, detailViewController, nil];
     self.splitViewController.viewControllers = viewControllers;

 ...

    [detailViewController release];

}

在 SecondViewController 中,有时我们有:

 MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
 UINavigationController *nav = (UINavigationController *)[delegate.splitViewController.viewControllers objectAtIndex: 0];
 NSArray *array = nav.viewControllers;
 // Retrieve the master view controller
 MasterViewController *masterVC = [array objectAtIndex:[array count] - 1];
 [masterVC selectRowManually:[NSIndexPath indexPathForRow:0 inSection:0]];

在 selectRowManually 中,我再次初始化 FirstViewController:

 UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

 if (rowNo == 0) {
      FirstViewController *newDetailViewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
      detailViewController = newDetailViewController;
 }
 ...

 UINavigationController *nav = (UINavigationController *)[delegate.splitViewController.viewControllers objectAtIndex: 0];

 // Update the split view controller's view controllers array.
 NSArray *viewControllers = [[NSArray alloc] initWithObjects:nav, detailViewController, nil];
 delegate.splitViewController.viewControllers = viewControllers;
 [viewControllers release];

 ...

 [detailViewController release];

如果我在这个时间点模拟内存警告(在 FirstViewController 再次显示之后),我会得到一个

-[UIView _invalidateSubviewCache]: message sent to deallocated instance ...

有一个堆栈跟踪

#0     0x012dd057 in ___forwarding___
#1     0x012dcf22 in __forwarding_prep_0___
#2     0x00b49a55 in -[UIView dealloc]
#3     0x00bbe52a in -[UIViewController setView:]
#4     0x00bc0eec in -[UIViewController unloadViewForced:]
#5     0x00bbcb0a in -[UIViewController unloadViewIfReloadable]
#6     0x00bbc15b in -[UIViewController didReceiveMemoryWarning]
#7     0x0006aec7 in -[SecondViewController didReceiveMemoryWarning] at SecondViewController.m:385
...

第 385 行在哪里

[super didReceiveMemoryWarning];

如果在 SecondViewController 的 buttonPressed 方法中我注释了我释放 detailViewContorller 的行,一切正常,但我泄漏了内存。如果我按原样保留该行,那么如果出现内存警告,应用程序就会崩溃。

我能做什么?

谢谢, 米海

【问题讨论】:

    标签: ipad memory uisplitviewcontroller


    【解决方案1】:

    我很好奇您发布 detailViewController 而不是 secondVC 的第一个代码块?因为你的 secondVC 在方法结束时没有释放。您应该在 dealloc 方法中释放 detailViewController,而不是在 SplitViewAppDelegate 中释放,因为它是拆分视图的根视图的一部分。

    干杯,希望对您有所帮助。

    【讨论】:

    • 感谢您的回答。 detailViewController 对于该方法是本地的。在detailViewController = secondVC这行之后,都指向同一个SecondViewController对象,所以释放detailViewController或者secondVC应该没有什么区别。
    • 内存崩溃通常是保留计数,所以我想您可以断点控制器的 dealloc 方法并执行一些 NSLog 以查看某些对象的保留计数,同时确保 dealloc 不会不必要地调用。跨度>
    • 我相信问题在于我从 SecondViewController 回到 FirstViewController 的方式,因为我没有更新 splitviewcontroller 的 viewController,就像我从第一个细节转到第二个细节时一样视图控制器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 2011-08-18
    • 2023-03-08
    • 2011-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多