I'm coding iOS 6.1 and learning Core Data.
If I have a Core Data entity/object in memory and I write it out, can I continue to hold a copy in memory, update it and write it out again?
Or, once I've written it out, do I have to read it in again to update it and then write it out again?
As you probably know already, Core Data uses both a persistent store and a managed object context. Data is loaded and saved using the managed object context.
The answer to your first question is yes. As long as your local reference variable is still in scope, you are able to update/save the content of the variable as many times as you want; remember, though, that it won't save to your back end unless you explicitly save your managed object context: [NSManagedObjectContext save:(NSError*)error].
Once that reference variable has gone out of scope, you'll need to fetch the managed object again if you want to edit it in any way.
Related
Imagine two managed object contexts, moc A and moc B filled with the same set of objects and sharing the same persistent store coordinator. Now, I delete an object from moc A and save the context. Will it still exist in moc B?
I tested that scenario and it seems like the objects still hang around in moc B, but I'm not sure if they are safe there, i.e. in a sense that I'll be able to write them back to the store.
The reason I'm asking is that I'd like to implement cut/copy/paste in a Core Data backed app but on copy I don't want to write the actual objects to the pasteboard and instead use the promise/data provider mechanism.
So let's say the user copies a bunch of managed objects and I write a promise to the pasteboard (an array of object IDs). Then, suppose the user deletes all these objects but later wants to paste them back somewhere. My data provider wouldn't be able to get them because they where deleted.
But I'm wondering what would happen if I had stored them in a private managed object context for safekeeping. Will they disappear from the safekeeping context after they're deleted from the main context?
the answer for question Will it still exist in moc B is : It depends :)
So, if your code is running on iSO 10 (or above) the answer is Yes, it will still exist because context A have deferent Generation of data.
if your code is running on iOS 9 (or previous), the answer again is: It depends. If any object in context B is fault, then if you will try to access any of properties (from this fault's object) your app will crash with sth like CoreData could not fulfill a fault. Otherwise you can access those data (they are saved in raw cache). But (probably, I never try that) if you will try to save objects that was deleted by other context then I would expected an error from CoreData.
The answer for Will they disappear from the safekeeping context after they're deleted from the main context?
is:
No, they do not disappear but in iOS 9 (or previous) if you have some faults you will never can fulfill them (because the are no more exist anywhere).
I have some Peoples profile, which I am saving in Core data. I receive them from server.
Next time when I run app, old data exists there, and I call a service call, which get more profiles including this.
I remove all the profiles and insert new.
When I try to work on existing screen, it crashes. I am pretty sure, that I changed database, and that object no more exists. While in reality, that object is inside CoreData but with another context.
Now, how can I improve this situation, that if I remove all Data and insert same data again, it shouldn't crash with existing data.
Let me know if anything wrong in Question, or I need to explain more.
Thanks.
If problem is really in "While in reality, that object is inside CoreData but with another context.", you can call the same object from needed context with it's NSManagedObjectID.
So just save your ids and pass them around, and when you need exact objects, call them from needed context with these ids
In updating an application with Core Data, a new functionality is a async process to synchronize informations between the app and the backend.
The problem is that in the app some NSManagedObject are built while doing a wizard process, at the end of the wizard the user can "save" or "discard" .
This means that the if the synchronization process is made during a wizard some objects can be saved to the persistent store with incomplete data and they "can't" be discharged (due to the save call at the the end of sync).
In the older version it wasn't an issue since the sync was a manual process.
I'm thinking about different solutions, the simplest is to delete the object if the user press cancel at the end or during the wizard, but I'm wondering if there is another better solution that can be useful in other similar cases.
I've found this question related to the issue:
How to Deal with Temporary NSManagedObject instances?
How to use Core Data models without saving them?
In the first question the suggestion is to leave the managed object context to nil while creating an NSManagedObject instance and adding its value before saving the object, but reading the comments it doesn't seems to work well, probably when your object has also some relationship with objects that have a managed object context and mine would.
Someone says also to create a child managed object context, but M. Zarra seems to not liking it ( and if you bought a Core Data book, you know that Marcus knows "something" about Core Data)
The second suggests to create an in-memory new store, but it doesn't explain how to move the object from one to another, I'm guessing a sort of copy would be fine.
Which one could be the best approach? I'm looking to a minimum refactoring and regression solution.
Within my Swift application, there are two classes that I interact with in almost 75% of the app. One is a set of settings called UserSettings, and the other is called Job. These both are stored in sqllite.
Most of the time it's just reading values already set, and on one areas it also writes. It seems strange to have to keep reinstantiating my settings and job services to communicate with my database to get back to me the same object i'm accessing across the board.
In a case like this, the options to me see to be either
constantly reading/writing to the database, or
do some sort of singleton accessed throughout the entire app.
I'm not sure how much Swift changes anything in terms of arriving at an answer to this question, but I wanted to seek the help of Stack Overflow. How do I set an object that I can access throughout the entire app? Or is it not ideal and instead I need to get it from my db every time?
Thanks so much.
I recommend you to read how core data works, I know you are managing your own store, but the architecture works fine. As a summary you can create a "context object"(this could be your singleton) who interacts with your store (sqlite) creating managed objects, you will work with this objects who are associated with the "context object", and when ever you need to save the changes, you ask the "context object" to write all the managed objects in the store.
Your managed objects need to be only a copy of the "context object" objects, so when you ask to "save" data to the "context object" you only copy back this managed objects. This will help with save multithread coding. (Your context object should work on a serialized queue).
Again this is just a summary, you should read how core data works to get a better picture.
Edit:
Read this blog: http://www.objc.io/issue-4/core-data-overview.html
The difference is that you only need one store and one context object.
My app needs to be able to disconnect from a server and connect to another one at whim, which necessitates dumping whatever persistent store we have. Issue here is that releasing the 'main' managed object context means whatever objects in it that I have laying around fault, which causes all sorts of unexpected little issues and crashes.
Is there a better way to 'reset' my stack/managed objects littered around the program than just calling release on everything in my Core Data stack?
You need to close down you Core Data stack from the top down.
Make sure that no managed objects are retained by any object other than the managed object context e.g. make sure the objects aren't held in an array owned by a UI controller.
Save the managed object context to clean up any loose ends.
Fully release the context and nil it. The context should never be retained by more than one object e.g the app delegate, anyway.
Send removePersistentStore:error: to the persistent store coordinator.
Use standard file operations to delete the actual store file.
Changing Core Data like this on the fly is difficult because Core Data isn't just a little database hung off the side of the app. It is intended to serve as the apps entire model layer. Since Apple is really into Model-View-Controller design, then the model is the actual core of the program (hence Core Data's name.) As such, you can't really turn it on and off the way you would a mere SQL database.
You might actually want to rethink your design so that you can change servers without having to shut down your entire data model. E.g. simply delete all managed objects associated with an unused server.
If you mean you want to fault all objects so they will be fetched again from your persistent store,
[managedObjectContext reset];