为什么我的视图在内存不足警告时消失?
我的应用程序有一个选项卡栏控制器,选项卡项目之一是分割视图控制器。它的主视图控制器(即索引 0 处)是一个从笔尖加载的导航控制器,因为它是自定义导航栏。
如果这听起来有点晦涩,那么这是由于 1) 无法将 SVC 添加到 IB 中的 TBC 和 2) iOS 4.2 splitview-navbar-colorTint 错误。事实上,自从昨天实施解决方法以来,我才遇到内存不足警告的问题。
在解决方法之前,我使用 2 个导航控制器初始化 SVC,并将其全部以编程方式添加到 TBC(由于 IB 对选项卡栏的限制),并且没有任何问题 - 好吧,除了那个苹果错误。
这个小解决方法演示也可以正常工作,甚至内存不足警告后。但它不涉及标签栏的额外开销。
但在我对解决方法演示的改编中,一切开始变得梨形。显示分割视图时发送内存不足警告,整个左侧(主视图)消失。在设备上的行为相同,事实上我首先在那里发现它。
我很困惑这是怎么回事。显示的视图(nav cont 的根视图)由表视图子类控制。我已经重写了 didReceiveMemoryWarning 但这没有帮助。此外(相应地!),超级视图不为零。这是一个 UITableView。完全正确。
所以,我认为导航控制器即将发布?但在哪里呢?为什么不在原始演示中呢?现在的区别是添加了我的标签栏控制器。这是我将其添加到选项卡栏的代码:
- (void) addTabItemSplitViewWithNavConRoot:(BOOL)hasRootNC {
// init master/detail views
SV1RootViewController *rvc = [[SV1RootViewController alloc] initWithNibName:@"SVC1RootView" bundle:nil];
SV1DetailViewController *dvc = [[SV1DetailViewController alloc] initWithNibName:@"SVC1DetailView" bundle:nil];
rvc.detailViewController = dvc;
UINavigationController *nc = nil;
if (hasRootNC) {
nc = [self.pSVC1.viewControllers objectAtIndex:0];
nc.viewControllers = [NSArray arrayWithObjects:rvc, nil];
nc.navigationBar.tintColor = [UIColor redColor];
} else {
nc = nil;
}
UIViewController *vc = (hasRootNC)? (UIViewController*)nc :rvc;
UISplitViewController *svc = [self newSplitViewControllerWithMasterVC:vc detailVC:dvc];
svc.delegate = dvc;
// init the tab bar item
svc.tabBarItem = [[UITabBarItem alloc] initWithTitle:(hasRootNC)? @"SplitView with Nav Root":@"Simple SplitView"
image:nil
tag:0];
// int the split view
NSMutableArray *controllersArray = [NSMutableArray arrayWithArray:self.pTabBarController.viewControllers];
[controllersArray addObject:svc];
[self.pTabBarController setViewControllers:controllersArray];
// cleanup
[nc release];
[rvc release];
[dvc release];
[svc release];
}
- (UISplitViewController*) newSplitViewControllerWithMasterVC:(UIViewController*)masterView
detailVC:(UIViewController*)detailView {
UISplitViewController *svc = [[UISplitViewController alloc] init];
NSMutableArray *controllersArray = [NSMutableArray arrayWithObjects:masterView, detailView, nil];
[svc setViewControllers:controllersArray];
return svc;
}
有人对我有想法吗? :)
这让我发疯!
My app has a tab bar controller, one of the tab items is a split view controller. It's master view controller (ie. at index 0) is a navigation controller loaded from a nib, due to it's custom navbar.
If that sounds a bit obscure, well it's down to a combination of 1) not being able to add an SVC to a TBC in IB and 2) the iOS 4.2 splitview-navbar-colorTint bug. And indeed, it's only since implementing the workaround yesterday that I've been experiencing a problem with low memory warnings.
Before the workaround I was initting the SVC with 2 nav controllers and adding it to the TBC all programatically (due to IB's restricions with th tab bar) and without and problems - well, except for that apple bug.
The little workaround demo also works fine, even after low memory warnings. But it doesn't involve the additional overhead of a tab bar.
But in my adaption of the workaround demo it starts to all go pear shaped. Send a low memory warning whilst showing the split view and the whole left side (master view) disappears. Behaviour identical on device, in fact I first discovered it there.
I'm puzzled what's going on. The view on display (the nav cont's root view) is controlled by a table view subclass. I've overridden didReceiveMemoryWarning but that doesn't help. Furthermore (correspondingly!), the superview isn't nil. It's a UITableView. Perfectly correct.
So, I'm thinking the nav controller is getting released? But where? And why not in the original demo? The difference now is the addition of my tab bar controller. Here's my code that adds it to the tab bar:
- (void) addTabItemSplitViewWithNavConRoot:(BOOL)hasRootNC {
// init master/detail views
SV1RootViewController *rvc = [[SV1RootViewController alloc] initWithNibName:@"SVC1RootView" bundle:nil];
SV1DetailViewController *dvc = [[SV1DetailViewController alloc] initWithNibName:@"SVC1DetailView" bundle:nil];
rvc.detailViewController = dvc;
UINavigationController *nc = nil;
if (hasRootNC) {
nc = [self.pSVC1.viewControllers objectAtIndex:0];
nc.viewControllers = [NSArray arrayWithObjects:rvc, nil];
nc.navigationBar.tintColor = [UIColor redColor];
} else {
nc = nil;
}
UIViewController *vc = (hasRootNC)? (UIViewController*)nc :rvc;
UISplitViewController *svc = [self newSplitViewControllerWithMasterVC:vc detailVC:dvc];
svc.delegate = dvc;
// init the tab bar item
svc.tabBarItem = [[UITabBarItem alloc] initWithTitle:(hasRootNC)? @"SplitView with Nav Root":@"Simple SplitView"
image:nil
tag:0];
// int the split view
NSMutableArray *controllersArray = [NSMutableArray arrayWithArray:self.pTabBarController.viewControllers];
[controllersArray addObject:svc];
[self.pTabBarController setViewControllers:controllersArray];
// cleanup
[nc release];
[rvc release];
[dvc release];
[svc release];
}
- (UISplitViewController*) newSplitViewControllerWithMasterVC:(UIViewController*)masterView
detailVC:(UIViewController*)detailView {
UISplitViewController *svc = [[UISplitViewController alloc] init];
NSMutableArray *controllersArray = [NSMutableArray arrayWithObjects:masterView, detailView, nil];
[svc setViewControllers:controllersArray];
return svc;
}
Anybody have ideas for me please? :)
It's driving me insane!!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决了。与以编程方式初始化分割视图控制器的奇怪组合有关,但用从主窗口 xib 读取的导航控制器注入它(所有这些都是因为 Apple bug 所需的自定义工具栏)。但我的猜测是 xib 的导航控制器正在卸载其视图。
所以现在我只是从笔尖取出整个 SVC,而不是手动构建它。实际上更整洁、更简单。
噢,伙计。我被这个问题的答案(“指定”答案!)引入歧途。 。我现在刚刚注意到这种更简单的方法也作为答案给出,并且实际上是最受欢迎的。完全忽略了它! ^^
Resolved it. Had sth to do with that wierd mix of programatically initialising a split view controller, but injecting it with a nav controller read from the main window xib (all because of the custom toolbar needed for the Apple bug). But my guess is that the nav controller from the xib was having it's view unloaded.
So now I just take the entire SVC from the nib, rather than construct it by hand. Much neater and much simpler actually.
Oh man. I was led astray by an answer to this question (the 'designated' answer!). I've now just noticed that this much simpler method is also given as an answer and is actually the most popular. Completely overlooked it! ^^
如果没有看到所有代码,我猜测非活动视图在内存警告期间被破坏。 (写着“didReceiveMemoryWarning”的代码,您可能有[super didReceiveMemoryWarning])
您需要确保在您的 loadView 方法中,需要添加的任何子视图都被重新添加到视图中,并相应地布局。希望有帮助。
或者,如果您匆忙或懒惰,只需阻止所有常见的事情发生即可。这可能很糟糕,并且可能会导致崩溃,但如果您不耐烦,这是一种替代方法。
Without seeing all of the code, I'm guessing the inactive view is destroyed during the mem warning. (The bit of code that says 'didReceiveMemoryWarning', you probably have [super didReceiveMemoryWarning])
You need to make sure that in your loadView method, any subviews that need to be added are re-added to the view, and layed out accordingly. Hope that helps.
Or if you are in a rush or lazy, just prevent all the usual things from happening. This is possible bad and may cause a crash, but it's an alternate approach if you are impatient.