views:

52

answers:

2

Hi, my app is based around two classes: Jam and JamItem, each with a TableViewController to display / add items.

The model contains two entities for the two classes, and there is an optional one-to-one relationship between them. JamItem has a name field and a price field. Jam has a quantity field. There are corresponding NSManagedObject classes for the two entities.

Both lists are based on table list view controllers and were modelled on the Recipes example on the Apple site. The JamListTableViewController displays all JamItem instances that have been added to the list. When I click add, a new instance of JamItemListTableViewController is created and pushed onto the nav stack. This lists JamItem instances that have been created. When a JamItem is selected, the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method creates an instance of JamItem and passes it back via a delegate to JamListTableViewController. This then creates a new instance of Jam and adds the JamItem to it and then saves.

I can run the app perfectly when it is fresh on the simulator and run the first time with a clean database!

The JamItemListTableViewController always works and I can happily add and remove 'jam items' from the list. However, if I stop the app and re-run, then try to add a new JamItem to the jam list (JamListTableViewController), it crashes when JamListTableViewController calls the [jam.managedObjectContext save:&error] and I get the error below, which I think is where it is trying to sort by name.

The NSFetchedResultsController in JamItemListTableViewController is configured to order by name. The NSFetchedResultsController in JamItemListTableViewController is ordered by JamItem.name

I hope this makes sense as I have been pulling my hair out for weeks now trying to find the solution. I think I might have (or have not) released an object, which is causing the JamItem list to flag that it has been updated and start trying to re-sort its list.

This is the dump of the error:

2010-09-29 07:20:00.443 Jams[12451:207] Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.  [<UINavigationItem 0x5b4dc30> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name. with userInfo {
        NSTargetObjectUserInfoKey = "<UINavigationItem: 0x5b4dc30>";
        NSUnknownUserInfoKey = name;
    }
    2010-09-29 07:20:00.446 Jams[12451:207] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UINavigationItem 0x5b4dc30> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
    *** Call stack at first throw:
    (
        0   CoreFoundation                      0x02577919 __exceptionPreprocess + 185
        1   libobjc.A.dylib                     0x026c55de objc_exception_throw + 47
        2   CoreFoundation                      0x02577851 -[NSException raise] + 17
        3   Foundation                          0x000d96b1 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 279
        4   Foundation                          0x00040868 _NSGetUsingKeyValueGetter + 147
        5   Foundation                          0x0003fd2e -[NSObject(NSKeyValueCoding) valueForKey:] + 278
        6   Foundation                          0x00043535 -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 381
        7   Foundation                          0x000f7c4f -[NSSortDescriptor compareObject:toObject:] + 128
        8   CoreData                            0x0237cb5e +[NSFetchedResultsController(PrivateMethods) _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 286
        9   CoreData                            0x0237d1b2 -[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 402
        10  CoreData                            0x023831bc -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 1804
        11  Foundation                          0x00035c1d _nsnote_callback + 145
        12  CoreFoundation                      0x0254fcf9 __CFXNotificationPost_old + 745
        13  CoreFoundation                      0x024cf11a _CFXNotificationPostNotification + 186
        14  Foundation                          0x0002b7c2 -[NSNotificationCenter postNotificationName:object:userInfo:] + 134
        15  CoreData                            0x022bf519 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 89
        16  CoreData                            0x0232eb33 -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] + 259
        17  CoreData                            0x022a1f78 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 1352
        18  CoreData                            0x022dba15 -[NSManagedObjectContext save:] + 149
        19  JamsApp                             0x000064b3 -[JamsListTableViewController insertJamItem:] + 168
        20  JamsApp                             0x00006405 -[JamsListTableViewController selectedJamItem:] + 43
        21  JamsApp                             0x00003f41 -[JamItemListTableViewController tableView:didSelectRowAtIndexPath:] + 143
        22  UIKit                               0x0033d718 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
        23  UIKit                               0x00333ffe -[UITableView _userSelectRowAtIndexPath:] + 219
        24  Foundation                          0x0004acea __NSFireDelayedPerform + 441
        25  CoreFoundation                      0x02558d43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
        26  CoreFoundation                      0x0255a384 __CFRunLoopDoTimer + 1364
        27  CoreFoundation                      0x024b6d09 __CFRunLoopRun + 1817
        28  CoreFoundation                      0x024b6280 CFRunLoopRunSpecific + 208
        29  CoreFoundation                      0x024b61a1 CFRunLoopRunInMode + 97
        30  GraphicsServices                    0x02ddc2c8 GSEventRunModal + 217
        31  GraphicsServices                    0x02ddc38d GSEventRun + 115
        32  UIKit                               0x002d9b58 UIApplicationMain + 1160
        33  JamsApp                             0x00001c0c main + 102
        34  JamsApp                             0x00001b9d start + 53
    )
    terminate called after throwing an instance of 'NSException'
A: 

I'd say check your nib to see if you have a connection to name, where name doesn't exist, but in suspect it would crash the first time too. Recheck everywhere you define name.

Jordan
Hi Jordan, thank you for looking. Yes, "Recheck everywhere you define name" is a good idea. I had a look at each point. I found that there are two refs to name when I create the NSSortDescriptor for the NSFetchedResultsController. All other refs are getters and setters from instances for details views or table cells. I went through those individually remming them out to see if it made any difference to the crash - none! Also I have nibs for detail views but none for the table list views.
Barnaby
A: 

Ok, so I fixed it myself.

I am not completely sure what was going on, but it's seems to me that a field that was there originally and then removed, seemed to be in the core data somewhere?

Anyway, the fix for me was to remove all the core data files and managed object files and delete the instance of the app in the sim, and start again.

It took minutes to do and solved the problem - now jam can flow happily again!

I would have rather solved the problem, however time is in short supply and I already spent too many hours looking at it!

Barnaby