views:

321

answers:

2

My app will allow users to create a personalised list of events from a large list of events. I have a table view which simply displays these events, tapping on one of them takes the user to the event details view, which has a button "add to my events".

In this detailed view I own the original event object, retrieved via an NSFetchedResultsController and passed to the detailed view (via a table cell, the same as the core data recipes sample). I have no trouble retrieving/displaying information from this "event". I am then trying to add it to the list of MyEvents represented by a one to many (inverse) relationship:

alt text

This code:

NSManagedObjectContext *context = [event managedObjectContext];
MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];
[myEvents addEventObject:event];//ERROR

And this code (suggested below):

//would this add to or overwrite the "list" i am attempting to maintain
NSManagedObjectContext *context = [event managedObjectContext];
MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];
NSMutableSet *myEvent = [myEvents mutableSetValueForKey:@"event"];
[myEvent addObject:event]; //ERROR

Bot produce (at the line indicated by //ERROR):

*** -[NSComparisonPredicate evaluateWithObject:]: message sent to deallocated instance

Seems I may have missed something fundamental. I cant glean any more information through the use of debugging tools, with my knowledge of them.

1) Is this a valid way to compile and store an editable list like this?

2) Is there a better way?

3) What could possibly be the deallocated instance in error?

--

I have now modified the Event entity to have a to-many relationship called "myEvents" which referrers to itself. I can add Events to this fine, and logging the object shows the correct memory addresses appearing for the relationship after a [event addMyEventObject:event];. The same failure happens right after this however. I am still at a loss to understand what is going wrong. This is the backtrace

#0  0x01f753a7 in ___forwarding___ ()
#1  0x01f516c2 in __forwarding_prep_0___ ()
#2  0x01c5aa8f in -[NSFetchedResultsController(PrivateMethods) _preprocessUpdatedObjects:insertsInfo:deletesInfo:updatesInfo:sectionsWithDeletes:newSectionNames:treatAsRefreshes:] ()
#3  0x01c5d63b in -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] ()
#4  0x0002e63a in _nsnote_callback ()
#5  0x01f40005 in _CFXNotificationPostNotification ()
#6  0x0002bef0 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#7  0x01bbe17d in -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] ()
#8  0x01c1d763 in -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] ()
#9  0x01ba25ea in -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] ()
#10 0x01bdfb3a in -[NSManagedObjectContext processPendingChanges] ()
#11 0x01bd0957 in _performRunLoopAction ()
#12 0x01f4d252 in __CFRunLoopDoObservers ()
#13 0x01f4c65f in CFRunLoopRunSpecific ()
#14 0x01f4bc48 in CFRunLoopRunInMode ()
#15 0x0273878d in GSEventRunModal ()
#16 0x02738852 in GSEventRun ()
#17 0x002ba003 in UIApplicationMain ()

solution

I managed to get to the bottom of this.

I was fetching the event in question using a NSFetchedResultsController with a NSPredicate which I was releasing after I had the results. Retrieving values from the entities returned was no problem, but when I tried to update any of them it gave the error above. It should not have been released.

oustanding part of my question

What is a good way to create this sub list from a list of existing items in terms of a core data model. I don't believe its any of the ways I tried here. I need to show/edit it in another table view. Perhaps there is a better way than a boolean property on each event entity? The relationship idea above doesn't seem to work here (even though I can now create it).

Cheers.

A: 

Assuming that you have named the MyEvents <--->> Event relationship as events

MyEvents *myEvents = (MyEvents *)[NSEntityDescription insertNewObjectForEntityForName:@"MyEvents" inManagedObjectContext:context];

NSLog(@"MYEVENTS: %@", myEvents);
NSLog(@"EVENT: %@", event);

// NSMutableSet to hold the events
NSMutableSet *events = [event mutableSetValueForKey:@"events"];

// Add the event to the set. Core Data takes care of the rest
[events addObject:event];

As per my comment, consider why you are creating a new Entity to manage a collection. NSFetchedResultsController and the NSFetchedResultsControllerDelegate protocol were designed to work closely with tableViews. Refer to Apple documentation on how to use these classes.

falconcreek
I have done it this way as I do not use a NSFetchedResultsController where I need to modify the data. I retrieve the "event" in a table view using a NSFetchedResultsController then pass this "event" to another view controller which is only concerned with this "event". This is where I am trying to add it to a list of "MyEvents" if the user initiates this action.I suppose there could be an attribute in the Event entity that states if this is to form part of the users MyEvents. I may want to add further info to "MyEvents" though.
michael
Did you try the code in my answer?Look at the CoreDataBooks sample code and study the interaction between the RootViewController, DetailViewController and EditingViewController. It seems that what you are trying to implement a similar workflow.
falconcreek
Thanks for your help and patience falconcreek. I did try your suggested code, and have updated my original question. I am indeed attempting something SIMILAR to the books sample code, but I am trying to add information I already have to a list, rather than adding an entirely new entity. I pass references around the same as the recipes sample code.
michael