释放详细视图控制器会导致内存问题
我有一个基于分割视图控制器的应用程序。在详细视图控制器中,将其称为 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];
:
如下
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的行,一切正常,但我泄漏了内存。如果我保持该行原样,那么如果出现内存警告,应用程序就会崩溃。
我能做些什么?
谢谢, 米哈伊
I have a split view controller based app. In the detail view controller, call it FirstViewController, when the user presses a button, I update the view controllers with a new view controller, call it SecondViewContorller, something like below:
- (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];
}
Inside the SecondViewController, at some point we have:
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]];
and inside the selectRowManually I initialize the FirstViewController again:
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];
If I simulate a memory warning at this point in time (after the FirstViewController has been displayed again), I get a
-[UIView _invalidateSubviewCache]: message sent to deallocated instance ...
with a stack trace of
#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
...
where line 385 is
[super didReceiveMemoryWarning];
If inside buttonPressed method of the SecondViewController I comment the line where I release the detailViewContorller, everything works out fine, but I leak memory. If I leave that line the way it is, then in case of a memory warning, the app crashes.
What can I do?
Thanks,
Mihai
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我很好奇你发布的detailViewController而不是secondVC的第一段代码?因为你的第二个VC在方法结束时没有被释放。您应该在 dealloc 方法中而不是在 SplitViewAppDelegate 中释放detailViewController,因为它是分割视图的根视图的一部分。
干杯,希望有帮助。
I'm curious about your first block of codes where you release your detailViewController instead of secondVC? Because your secondVC was not released at the end of the method. You should release detailViewController in the dealloc method instead in the SplitViewAppDelegate since it is part of the root views of split view.
Cheers, hope it helps.