I've created an NSManagedObject class that matches the corresponding Core Data entity. The class has an initializer so I can pass in property values and assign them.
Once the NSManagedObject class is initialized and ready to be saved to Core Data, how exactly do you save it?
The examples I've seen all start by creating a new class through NSManagedObjectContext. I don't want to go that route since I'm creating the class like any other class.
Is there some way to pass this object to NSManagedObjectContext and call its save() method.
It sounds like you're probably not properly initializing your managed objects. It's not enough to assign property values in an initializer-- you have to use the designated initializer. The examples you've seen all use an NSManagedObjectContext because the designated initializer for a managed object requires one. If you don't provide one, you're not using the designated initializer, and you won't be able to save your objects in Core Data.
This is one of the base requirements of Core Data. You must use managed objects, which must be initialized properly, and doing this requires a context.
You don't save a managed object-- you tell a context to save any changes it knows about, which includes changes to any of its managed objects. You can make that more fine-grained by creating a new context that only knows about one new object. But saving an object on one context doesn't automatically let other contexts know, so you end up adding some complexity to keep changes synced.
Apple's Core Data Programming Guide covers this in detail with sample code.
Related
Even though I use a specific ORM framework, Bold for Delphi, I'm more interested in framework agnostic theoretical view on the problem.
So the question is about having a persistent object and a transient attribute with initial value tag.
The initial tag specifies the value attribute will get when instance of owning object is created.
However when subsequently loading this object from persistence, what should be the value of transient attribute?
Should initial value tag be applied again? Logically, it should, otherwise it will be left unassigned (null).
I couldn't find any specs on this particular case in any of the docs.
We can't create object up to the DB record only - because we would lose all transient attributes. So, when you are loading a persistent object, it can be done only into the already created instance. And there is no other way of instantiating without using the base object constructor, which sets the initial values. Of course, some language could make a workaround about it, but why?
I have two entities - A and B. A includes a set of Bs. Every time I create a B, I want to make sure I add it to a special instance of A.
Looking at the NSManagedObjectClass reference, it is very clear that I should NOT be overriding the init method. So where is the best place to "catch" the creation of B? The only way I can see is to use validateForInsert, but I'm concerned that that's not really what it's meant for, and thus may cause headaches down the road. Is there a better option?
From the NSManagedObject documentation:
awakeFromInsert
Invoked automatically by the Core Data framework when the receiver is first inserted into a managed object context.
Subclass this method on your entity's class.
I'm not sure how to maintain a bi-directional relationship between my core data entities and some objects that are instantiated when the entities are created and committed to the database.
I have many subclassed MKAnnotation objects with one-to-one relationships to the entities. Every time my fetchedResultsController executes a new fetch, I am assuming that the results from a previous fetch are released and the NSManagedObjects that are fetched are remapped in memory. So my one-to-one relationships are broken. If I can save a pointer to the MKAnnotation objects in core data, that would fix half of the problem (the relationship in one direction). Does this make sense? How would you do this?
I delete all of the core data content when the application is restarted, so long term persistence of the relationship information is not a concern that I have.
Mixing pointers and managed objects is usually futile because Core Data has so many optimizations in place that direct memory management is all but impossible e.g. an object may revert to a fault.
You're really going about this the wrong way. Core Data isn't primarily a persistence API, its a data modeling API intended to provide the complete model layer of a Mode-View-Controller design app. As such, you can use it without saving anything at all. If you are using Core Data and you have data such as map annotation, the annotation should be modeled in Core Data. Doing so will simplify everything.
Since there is no MSAnnotation class but merely a MKAnnotation protocol, the simplest solution in this case would be to create a NSManagedObject class that implements the MKAnnotation protocol. You can either convert location data like CLLocationCoordinate2D into NSValues or better yet, just make attributes for them. Since the class implements the protocol, you could pass the managed objects anywhere you would pass any protocol object.
I am implementing "duplicate" functionality in my iOS application. I'm using the following workflow:
present a list of managed objects in initial context in root view controller
when user taps on a row, create a new context pass it to "detail" view controller with duplicated managed object ([[DetailController alloc] initWithObject:clonedObject inContext:newContext]).
However I am struggling with the concept of reassigning relations from source object to the cloned one since their managed object contexts differ. What would be correct approach to this:
Should I just reassign the pointer value and do not bother about MOC or...
I should refetch the values in new context depending on their unique identifiers?
Any other option I did not think of?
P.S. Contexts are using same persistent store coordinator.
Managed object IDs are thread safe. As such, you can pass a managed object ID to the MOC in your view controller, retrieve that object via existingObjectWithID:error, then perform the duplication in that context. This way, the objects never cross MOC boundaries.
In the project I'm working on, we have an aggregate domain object. The factory object handles the creation of the unique id for the object. But there is a separate import process which creates the same object initially without the id. To add the imported object to the system, we are now forced to do a field by field copy to a new object since we can't just set the id for it for obvious reasons. Could anyone suggest a better way of handling this situation?
Possibilities:
If the import process allows it, inject your domain object when it is creating so it actually populates your object.
Have your object's implementation be a wrapper around the one created by the import process. Change your factory accordingly.