I’m building a tab bar application in which there are three tabs, each of which loads a different .plist into a drill-down table view. I’ve finally been able to set it up so that at the very least the first level displays, but my app crashes if you try to select one of them. I’m not sure if it is the way I linked in in interface builder (more later) but there’s an obvious issue.
The only thing that I built in my app delegate was a navigation controller to manage my view. I use the tab bar template, so that was already created. I changed the first view’s mode to navigation controller. I created it as an IBOutlet so I could link the Navigation controller to the proper variable I created in the App Delegate.
Here is my first view’s initialization code:
@interface IndustryTableView : UITableViewController {
NSDictionary *industryData;
NSArray *tableDataSource;
NSString *CurrentTitle;
NSInteger CurrentLevel;
}
@property (nonatomic, retain) NSDictionary *industryData;
@property (nonatomic, retain) NSArray *tableDataSource;
@property (nonatomic, retain) NSString *CurrentTitle;
@property (nonatomic, readwrite) NSInteger CurrentLevel;
@end
My files are imported into the implementation. Here is the relevant code from that
- (void)viewDidLoad {
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:@"IndustryData.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.industryData = tempDict;
[tempDict release];
if(CurrentLevel == 0) {
NSArray *tempArray = [[NSArray alloc] init];
self.tableDataSource = tempArray;
[tempArray release];
self.tableDataSource = [self.industryData objectForKey:@"Rows"];
self.navigationItem.title = @"Back";
}
else
self.navigationItem.title = CurrentTitle;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:@"Children"];
Jqt62m7AppDelegate *AppDelegate = (Jqt62m7AppDelegate *) [[UIApplication sharedApplication] delegate];
if([Children count] == 0) {
DetailView *dvController = [[DetailView alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
[AppDelegate.indNavControl pushViewController:dvController animated:YES];
[dvController release];
}
else {
//Prepare to tableview.
IndustryTableView *indViewControl = [[IndustryTableView alloc] initWithNibName:@"IndustryView" bundle:[NSBundle mainBundle]];
//Increment the Current View
indViewControl.CurrentLevel += 1;
//Set the title;
indViewControl.CurrentTitle = [dictionary objectForKey:@"Title"];
//Push the new table view on the stack
[AppDelegate.indNavControl pushViewController:indViewControl animated:YES];
indViewControl.tableDataSource = Children;
[indViewControl release];
}
}
Error on crash is Program received SIGABRT, a very common issue. It occurs at the line [AppDelegate.indNavControl pushViewController:indviewControl animated:YES]; If this helps anybody, this is the debug code:
(
0 CoreFoundation 0x00dc25a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f16313 objc_exception_throw + 44
2 CoreFoundation 0x00d7aef8 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x00d7ae6a +[NSException raise:format:] + 58
4 UIKit 0x0020f0fa -[UINib instantiateWithOwner:options:] + 2024
5 UIKit 0x00210ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:] + 168
6 UIKit 0x000c6628 -[UIViewController _loadViewFromNibNamed:bundle:] + 70
7 UIKit 0x000c4134 -[UIViewController loadView] + 120
8 UIKit 0x0021ddd8 -[UITableViewController loadView] + 80
9 UIKit 0x000c400e -[UIViewController view] + 56
10 UIKit 0x000c2482 -[UIViewController contentScrollView] + 42
11 UIKit 0x000d2f25 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
12 UIKit 0x000d1555 -[UINavigationController _layoutViewController:] + 43
13 UIKit 0x000d27aa -[UINavigationController _startTransition:fromViewController:toViewController:] + 326
14 UIKit 0x000cd32a -[UINavigationController _startDeferredTransitionIfNeeded] + 266
15 UIKit 0x000d4562 -[UINavigationController pushViewController:transition:forceImmediate:] + 932
16 UIKit 0x000cd1c4 -[UINavigationController pushViewController:animated:] + 62
17 Jqt62m7 0x00002a78 -[IndustryTableView tableView:didSelectRowAtIndexPath:] + 952
18 UIKit 0x0008bb68 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
19 UIKit 0x00081b05 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219
20 Foundation 0x0079b79e __NSFireDelayedPerform + 441
21 CoreFoundation 0x00da38c3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
22 CoreFoundation 0x00da4e74 __CFRunLoopDoTimer + 1220
23 CoreFoundation 0x00d012c9 __CFRunLoopRun + 1817
24 CoreFoundation 0x00d00840 CFRunLoopRunSpecific + 208
25 CoreFoundation 0x00d00761 CFRunLoopRunInMode + 97
26 GraphicsServices 0x00ffa1c4 GSEventRunModal + 217
27 GraphicsServices 0x00ffa289 GSEventRun + 115
28 UIKit 0x00022c93 UIApplicationMain + 1160
29 Jqt62m7 0x00001cc9 main + 121
30 Jqt62m7 0x00001c45 start + 53
)
terminate called throwing an exceptionCurrent language: auto; currently objective-c
(gdb)
So that’s a long way of me asking – why is my program crashing?
It seems that the exception is being caused when the user selects a row in the table view cell. This is because you are creating an instance of
IndustryTableViewwith the nib name ofIndustryView. Try changing this line of code:To this:
Note that, in most cases, giving
nilfor the bundle doesn’t make a difference and should generally be done to imply the main bundle. Although you didn’t provide the entire stack trace, it seems apparent that the issue is arising when-loadViewis called on yourIndustryTableView, and it tries to load from the wrong nib.