browsing in some core data pages online i found a tutorial that use an interesting technique, i never seen nor used it before, but actually looks pretty smart.
Instead of working with long methods, with FRC, and so on, they place the results of the fetchResultController in an array, so they can use it to do all the work.
here is the link.
http://www.appcoda.com/introduction-to-core-data/
What do you think are the errors of using this approach? it's a valid one?
It works, but it completely defeats the purpose of the NSFetchedResultsController. The FRC is meant to fetch objects from Core Data in batches, which is much more efficient. If you create an array from all the fetched objects, you will load all those objects into memory at once (if you have a gazillion entities, then this will be a problem). Also if any of your data ever changes (you get notified by the delegate), then you will need to perform the fetch again, then recreate the array yourself.
Related
i'm refactoring my app. Currently, I store objects in a .plist for further processing. It works fine, but I thought it was about time to dive into CoreData.
My app fetches data from a web service. This data I parse into individual objects.
I use the properties of these objects to fill Tableviews.
While refactoring, I could just bluntly store the whole object as a transformable with CoreData, as far as I understand.
I could also define an entity with attributes similar to the properties of my object.
Is there any Best Practice here? I think the first approach makes it easier to do the refactoring, but I somehow think I'm missing out on advantages of CoraData in that case. Like maybe performance?
Do not store objects as transformable. You will get just DB where it is not possible to fetch some separated objects based on some criteria. You will need to fetch all DB in memory and than work with it. So it will be the same as plist file and you will waste the effort. Just use entities with proper attributes. CoreData is fast, you don't need to worry about performance.
Transformables are generally a good idea only for attributes that Core Data doesn't know how to represent. They let you use a binary data blob as a fallback, but they're never ideal. They can also be used if you absolutely, definitely, will never ever need to filter or sort a fetch request based on the attribute value. In that case they're still not great, because there's extra unnecessary work.
If you need to (or might possibly someday need to) filter or sort a fetch request based on attribute values, don't use a transformable. They can't be used for either purpose beyond extremely basic stuff like checking to see if the value is nil.
OK, I owe you.
I asked a question without investigating things properly.
The real answer is to understand NSManagedObjects.
Sorry for bothering you
A few weeks ago, I decided to learn Core Data for my new project and apply it to my entire model. There was a steep learning curve, but eventually I got familiar with the stack and I'm now rather comfortable with at least the basic concepts and the few common pitfalls such as thread concurrency.
I have to say, the first few weeks after getting comfortable where pretty amazing. NSFetchedResultsController give you a good way to communicate between my model and my controllers. However the more I use Core Data, the more annoying it gets.
As a concrete example, my app fetches a few pieces of data from my server (the posts) which appear in a feed. Each post has an owner, of class User, which I also fetch from the server. Now, Core Data has been great for managing the realtionship between a post and a user. The relationship is updated automatically and getting the post's origin is as simple as calling post.owner. However, there are also inconveniences:
1.Core Data forces objects to the disk that I do not want forced to the disk. This is probably the main issue. With the posts, I do not want them to be forced to disk, and would rather make calls to the server again. Why? Because the more posts I store persistently, the more housekeeping there is to do. A post can be edited, deleted, flagged, etc... and keeping those posts locally means having to plan updates.
2.Having to constantly worry about concurrency of contexts, objects and the likes. I wrote an object factory that always returns objects on the right thread and the right context, but even then bugs occur here and there, which quickly becomes frustrating.
3.Decreased performance. Perhaps the least important one at this point, going from cached objects to Core Data has taken a (barely noticeable) toll on the performance of my application (most notably the feed).
So what are your recommendations regarding Core Data? Would you suggest a different approach to Core Data?
I was thinking of a hybrid caching + Core Data where I store the information I will actually use many times (such as users) persistently and then use the RAM for things like posts, or simply creating posts without an NSManagedContext. Input welcome!
Core Data forces objects to the disk that I do not want forced to the disk.
It does no such thing. If you don't want to save your Post objects to the persistent store, don't put them in Core Data and don't make them managed objects. Your User object can have a posts property even if the Post object is not managed by Core Data. Managed objects can have properties of any type, not only to other managed objects.
Having to constantly worry about concurrency of contexts, objects and the likes.
Concurrency is complex no matter how you model your data. It's a fundamentally complex problem. You're encountering it with Core Data because you're using Core Data. If you use something else, you'll deal with it there.
Decreased performance.
"Product" menu --> "Analyze" and run Instruments to find out why. There's no reason this should happen, and you have the tools to discover what's actually going on.
Typically I use Core Data in my applications, but for my current project I don't need data to persist launch to launch.
Because of that, I'm wondering how I should store my data. It's not going to be tens of thousands of items or anything, hundreds at the high end most likely.
I'm still going to create an NSObject subclass to represent each "entry" in the database, but what should I store that in? A simple NSMutableArray that's a property? Should I have a distinct model class? Should I still be using Core Data somehow?
What's the accepted/best practice for a situation like this?
The persistence aspect is only one part of core data. The fetch requests, object graph maintenance and entity modeller are arguably just as important.
If you don't want to persist your data, use the in-memory store type when creating your core data stack.
I would say that if you are familiar with Core Data why dont use it?
But alternatively of course you can stick with NSUserDefault. Atm i'm using the NSCache class.
Good explanation of NSCache and how to use it
Apple's Doc
I would give it a shot if you dont like to use CD for your current Project..
Since you're not worried about persistence, it seems simplest to just use a wrapper around an NSMutableArray (or NSMutableDictionary if indexing is more important that ordering) Since you can apply NSPredicates to arrays you've still got the ability to do very dynamic database style sorting and searching without some of the drawbacks of core data.
Use a wrapper instead of just using an array because that gives you a convenient place to put sorting and searching options, as well as possibly giving you better access to KVO operations.
I am developing an app which consists of a UINavigationController and UITableViews, there will be many items (50+) at the root view of the nav controller and maybe 30 rows in each of the detail views.
What is the most efficient way to populate the lists? Core Data or Plists?
There is scope within the specification to push updates to the lists on a monthly basis, so they always stay current. Would this affect the choice, which method is easier to bulk update?
Thanks
I would choose Core Data.
It is relatively easy to use; and it gives you more flexibility if the app needs to grow. Core Data can be backed by SQLLite, and thus can be quite performant. Also bulk updates is manageable.
Core Data is by far the best, especially since you want to be able to make updates to this data later on
Regarding updates. I wouldn't 'push' these out but rather have the app poll for them, perhaps on launch, then fetch anything new in the background.
Edit: Also with Core Data and using a NSFetchedResultsController it is very easy to smoothly animate in new records into a UITableView as they are added in the background to the data store
Imho, I would try to keep things simple, following the good old KISS principle.
In your current case, it seems that you just need to display read-only data, so all you need is the data (say a file, in plist format, or xml, or json, or csv, or whatever. just parse the file, populate your business objects, add them to an array. Use that array for your master and detail view. No need for core data here (asumming by 50+ you don't mean 50 - 50'000, because in that case, core data's memory management would help ;-)
If in the future you need to handle updates, you will either update the whole list, thus in fact just replace the old file (simple), or do incremental changes. I would only recommend to consider to start using core data in the latter case.
I'm personally using core data in a couple of projects, and I love it. But I wouldn't recommend it just because it's there, after all it brings overhead and complexity. If you want to use core data, you'll need to invest some time to understand it's concepts. Don't underestimate that, there's a lot of stuff to read and understand, and probably a couple of WTF moments (just look for core data questions here in SO).
Just to be clear: I don't want to talk you out of using core data, I'm just asking as your mother probably would: do you really need it?
I have a pretty basic question.
If I have two entities with a relation between them (lets say entityOne has a to-many relationship to entityTwo).
When I fetch entityOne, does it automatically fetch its relationships? Or do I have to fetch them as well and assign them to its corresponding entity?
I thought this would be actually better to ask in the chat since its a simple question, but I dont have the reputation needed yet.
Since I can't post my question because its too short, I'll just ask another question.
In the same project, I have a rootViewController which fetches the entities. Now if I want to add an event I have to send the user to another view, with textFields and such. I ended up creating an array "eventArray" for each of those viewControllers since I couldn't find a more efficient way of doing this.
Lets say I have in rootViewController a NSMutableArray *eventsArray and in addEventViewController I have also an NSMutableArray *eventsArray which gets set before pushing addEventViewController (addEventViewController.eventsArray = self.eventsArray).
How do I do this more efficiently? I'm pretty sure this isn't the right way of doing it.
In answer to your first question:
This situation is handled by Core Data automatically, and the mechanism is called "faulting". Apple has some helpful documentation on this. Simply put, the related objects aren't fetched, but when you try to access them, Core Data will automatically retrieve them from the persistent store.
Of course, there may be situations where this one-by-one fetching of related objects (perhaps to display something about the related objects in a table for example) slows down your application.
In this situation you can use the setRelationshipKeyPathsForPrefetching: method on NSFetchRequest to retrieve these objects upfront. It's all a question of balancing memory usage and performance.
Faulting is a very important part of Core Data, and I'd strongly suggest reading the documentation carefully to make sure you have a good understanding of how and when it is used.