7

I'm trying to write a favorites system for my app. I've already converted my model to a managed object. So imagine the user is presented a screen with a list of such objects. They can choose to save some to their favorites, which will persist them in core data.

The problem is, when I create all of these model objects, I do so with the managed object context. If the user saves a single one to their favorites, it's going to save the whole context, and persist every single entity. The extras won't be in their favorites, since adding to favorites constructs a "favorite" entity that gets saved and points to the object, which the others won't have. But all of the other objects will be saved needlessly.

What's the standard way out of this / standard way to design an iPhone favorites system? Should I separate my model into two classes, the one I show the user, and then one that saves to the db? That way I could construct my models without putting them into the MOC. But that would be a duplicated class with all the same fields.

Tesserex
  • 17,166
  • 5
  • 66
  • 106

2 Answers2

7

There is not really a standard way to do this because Core Data expects you to save the objects you create. However, if you create the objects with:

id object = [[NSManagedObject alloc] initWithEntityDescription:entity inManagedObjectContext:nil];

They won't have a context to save against. Then for the ones you need to save you can:

[[self managedObjectContext] insertObject:object];

Then call -save: on the context and only those that have had their context set will save.

Abizern
  • 146,289
  • 39
  • 203
  • 257
Marcus S. Zarra
  • 46,571
  • 9
  • 101
  • 182
  • And this is safe? I saw that the convenience method for constructing NSMOs replaces a pretty large chunk of code. – Tesserex Aug 26 '10 at 16:06
  • Yes it is safe, what convenience method? The method I described is the same as calling `[NSEntityDescription insert...]`. The only difference is that the `NSEntityDescription` method returns an autoreleased object. – Marcus S. Zarra Aug 26 '10 at 16:18
  • 1
    Ok, you just have your second thing backward. The correct call is `[[self managedObjectContext] addObject:object]`, the converse that you have there doesn't exist. – Tesserex Aug 26 '10 at 16:51
  • Correct, coding from memory and without a compiler can produce such minor errors :) – Marcus S. Zarra Aug 26 '10 at 19:49
  • Hi @MarcusS.Zarra. I know this is an old answer of yours, but more recent discussion elsewhere is to avoid using a nil context, due to various possible issues (e.g. https://stackoverflow.com/a/3868651). Is there a way to achieve this using child contexts instead? I can see easily enough how a child context would be created for the purpose of generating the results, but saving it would just dump everything back into the parent. Could the same insertObject method be used to move specific 'favorites' from the child to the parent, and leave the rest? – TheNeil Apr 23 '19 at 20:39
  • @TheNeil this is a VERY old answer and out of date :). You can use a child context to achieve nearly the same thing and if you don't want to save those objects just release the context. Problem is, mixing and matching. The choice is to save the context or toss. To get more grainular I would pre-delete the objects before calling save. Perhaps using a transitory boolean property on the objects and deciding to delete then save. – Marcus S. Zarra May 03 '19 at 04:48
-1

Wouldn't it be easier to have an isFavorite property on your managed objects. Then in your favorites view you can filter based on that?

Elfred
  • 3,851
  • 22
  • 16
  • 4
    But that still doesn't get around the fact that I'm saving a whole lot of data that I don't need. – Tesserex Aug 26 '10 at 16:21