问题
In my SDK 3.0 core data based app, I have a tab bar controller managing 4 tabs. From time to time, apparently randomly, when I launch the app, it crashes with the following message:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Directly modifying a tab bar managed by a tab bar controller is not allowed.'
However, I am not modifying in my code any of the tabs except for the following. In practice, all of the navigation controllers or controllers in the tabs have been setup using IB, and in my code I have declared two of them as outlets, since I need to access them in my app delegate applicationDidFinishLaunching() method to setup their core data managedObjectContext as follows:
[self managedObjectContext];
[self managedObjectModel];
[self persistentStoreCoordinator];
[rootViewController retain];
rootViewController.managedObjectContext = self.managedObjectContext;
Is this not correct? If so, why?
The only reference to the problem I have seen on the web is here:
http://discussions.apple.com/thread.jspa?messageID=9716886
However, the problem still persists even after deleting and recreating the tab bar controller from scratch in IB.
Any clue? Thanks in advance.
回答1:
I've had this problem too. Do you have an outlet to the UITabBar
itself (not the UITabBarController
) in the nib? When I removed that, I stopped having problems.
Sorry this isn't a 100% reliable explanation, but this workaround cleared the problem up for me.
回答2:
I've gotten this exception a few times, especially when changing things with localizations. Cleaning the targets and then rebuilding seems to work around the issue.
回答3:
I quickly wrote the following class and showing/hiding tab views from UITabBarController worked like magic:
TabBarDesigner.h
#import <Foundation/Foundation.h>
@interface TabBarDesigner : NSObject
{
}
+(void) setTabBarController:(UITabBarController *)tabBarController
items:(NSArray *)tabBarItems
viewControllers:(NSArray *)viewControllers;
+(void) removeItemsInRange:(NSRange) range;
@end
TabBarDesigner.m
#import "TabBarDesigner.h"
static NSArray *_tabBarItems = NULL;
static NSArray *_viewControllers = NULL;
static UITabBarController *_tabBarController = NULL;
@implementation TabBarDesigner
+(void) setTabBarController:(UITabBarController *)tabBarController
items:(NSArray *)tabBarItems
viewControllers:(NSArray *)viewControllers
{
if (tabBarItems && viewControllers && tabBarController)
{
if ([tabBarItems count] == [viewControllers count])
{
[_tabBarItems release];
[_viewControllers release];
_tabBarItems = [tabBarItems copy];
_viewControllers = [viewControllers copy];
_tabBarController = tabBarController;
}
}
}
+(void) removeItemsInRange:(NSRange) range
{
if (_tabBarController)
{
if ( range.location < ([_tabBarItems count] - 1) )
{
if ( (range.length + range.location) < [_tabBarItems count] )
{
NSMutableArray *tabBarItems = [_tabBarItems mutableCopy];
[tabBarItems removeObjectsInRange:range];
NSMutableArray *viewControllers = [_viewControllers mutableCopy];
[viewControllers removeObjectsInRange:range];
[_tabBarController setViewControllers:viewControllers];
NSUInteger i;
for (i = 0; i< [viewControllers count]; i++)
{
UIViewController *vC = [viewControllers objectAtIndex:i];
vC.tabBarItem.image = [[tabBarItems objectAtIndex:i] image];
vC.tabBarItem.title = [[tabBarItems objectAtIndex:i] title];
vC.tabBarItem.tag = [[tabBarItems objectAtIndex:i] tag];
}
[tabBarItems release];
[viewControllers release];
}
}
}
}
@end
A sample of how to use this class: In your MyAppDelegate.m
#import "TabBarDesigner.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[TabBarDesigner setTabBarController:_tabBarController
items:[_tabBarController.tabBar items]
viewControllers:[_tabBarController viewControllers]];
// remove the first 3 tabs
[TabBarDesigner removeItemsInRange:NSMakeRange(0,3)];
// show all tabs
[TabBarDesigner removeItemsInRange:NSMakeRange(0,0)];
// continue with your code
}
Cheers!
来源:https://stackoverflow.com/questions/1108782/tab-bar-controller-raising-nsinternalinconsistencyexception