Hello guys. I'm a newbie to iphone development and I've been struggling with an EXC_BAD_ACCESS error I got a couple of days ago. I'm basically taking the Stanford iphone class independently and I am trying to pass an array of NSManagedObjects to a TableViewController that's supposed to display them. The application launches in the simulator and displays the data in the tableView but it immediately errors out with an EXC_BAD_ACCESS.
I followed instructions here and other places on how to use NSZombieEnabled to identify prematurely released objects but this one comes without any helpful msgs even with NSZombieEnabled. My guess is it must be caused by something trying to access unassigned memory that wasn't released through release/autorelease. Or else it would have been picked up as zombie object like the other errors I have been able to fix. I'm not a c expert but does that mean something like that could happen if I were to declare an object and send it a message without ever instantiating it? I looked through my code to see if I had anything like that and I came up empty.
I have the stack trace in the debugger for this but I'm not sure how to make use of it. I'm a little frustrated because I can't use breakpoints in the code to narrow down the problem any further since it seems to happen after the app has finished loading. I thought the app would just stay idle if there was no possible user interaction. Is it failing at the tail end of the load where I can't easy see it or is jut doing stuff in the background after it's done loading. And I would much appreciate any tips on how to read the stacktrace for this.
I've typed out my stacktrace below (couldn't figure out how to copy it from the debugger)
0 objc_msgSend
1 ??
2 -[NSManagedObject dealloc]
3 -[_PFManagedObjectReferenceQueue _processReferenceQue:]
4 _performRunLoopAction
5 ___CFRunLoopDoObservers
6 CFRunLoopRunSpecific
7 CFRunLoopRunInMode
8 GSEventRunModal
9 GSEventRun
10 UIApplicationMain
11 main
And the two main classes in my program are the top level delegate class and the ViewTableController it calls.
`- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
UINavigationController *contactsNavigationController = [[self createContactsNavigationController] retain];
//UINavigationController *recentsNavigationController = [[self createRecentsNavigationController:photos] retain];
tabBarController.viewControllers = [[NSArray alloc] initWithObjects: contactsNavigationController, nil];
[contactsNavigationController release];
//[recentsNavigationController release];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
}
-(UINavigationController *)createContactsNavigationController {
UINavigationController *contactsNavigationController = [[UINavigationController alloc] init];
UITabBarItem *contactsTabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem: UITabBarSystemItemContacts tag:0];
contactsNavigationController.tabBarItem=contactsTabBarItem ;
[contactsTabBarItem release];
PersonListViewController *personListViewController = [[PersonListViewController alloc] initWithStyle:UITableViewStylePlain];
NSManagedObjectContext *context = [self managedObjectContext];
personListViewController.managedObjectContext=context;
personListViewController.contacts = [self createContacts];
[context release];
personListViewController.title=@"Contacts";
[contactsNavigationController pushViewController:personListViewController animated:false];
return [contactsNavigationController autorelease];
}`
`- (NSArray *)readContacts {
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *filePath = [path stringByAppendingPathComponent:@"FakeData.plist"];
NSArray *plist = [[NSMutableArray arrayWithContentsOfFile:filePath] retain];
return [plist autorelease];
}
- (NSMutableArray *)createContacts {
NSArray * plist = [[self readContacts] retain
NSMutableArray *contactNames = [[NSMutableArray alloc] init];
NSMutableArray *contacts = [[NSMutableArray alloc] init];
for (NSDictionary *photo in plist) {
NSString *contactName = [photo objectForKey:@"user"];
Person *contact = nil;
if (![contactNames containsObject:contactName]) {
contact = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext];
contact.name =contactName;
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"SHIT the save person FAILED!!! %@",error);
}
[contacts addObject:contact];
[contactNames addObject:contactName];
} else {
contact = [contacts objectAtIndex:[contactNames indexOfObject:contactName]];
}
[contactName release];
Photo *image = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:managedObjectContext];
image.imageFile = [photo objectForKey:@"path"];
image.imageName = [photo objectForKey:@"name"];
image.owner = contact;
contact.photos = [NSSet setWithObjects:image,nil];
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(@"SHIT the save photoFAILED!!! %@",error);
}
[image release];
[contact release];
}
[plist release];
return [contacts autorelease];
}
I apologize if my code is too crappy to read.
Thanks for the help guys.