27. Core Data
Get a new Fatal Error episode every week by becoming a Patreon supporter!
This week, Soroush and Chris talk about why they'd basically never use Core Data.
- Mike Ash comment on Hacker News (copied below)
- Cache Me If You Can: Soroush's post on why not to use Core Data as a cache
- Ruby Midwest 2011 - Keynote: Architecture the Lost Years by Robert Martin
- Caleb Davenport: Ditching Core Data (and using YapDatabase)
- ACID Guarantees
Mike Ash:
The short and easy answer is no, never.
Core Data is just not a good technology. People on the other side of this debate will say that there's an appropriate time for everything, but nothing makes sense for everything, so you have to choose based on your needs. This is half true. It misses the fact that some things are just plain bad and are never better than the alternatives in any situation, and IMO Core Data is in this category.
There are several fundamental problems with it.
First, the API is awful. If you want decent model objects in memory you either have to do a bunch of manual work, or use a third-party tool like mogenerator. Even then, the result is a massive soup of mutable objects with no intelligence. The structure of the API encourages passing the entire context around everywhere, which basically turns all of these objects into global variables. Look no further than popular Core Data wrapper APIs to see how bad this can get. For example, ObjectiveRecord[1] adds class methods for looking up objects using a predicate. Modularity? Separation of concerns? Perish the thought.
Second, it ties your on-disk representation to your in-memory representation way too strongly, and this makes it more difficult to choose appropriate structures for either one, and more difficult to make changes to either one.
Third, it locks you into the technology something fierce. Core Data is so different from everything else that once you build your model layer on it, you're just about stuck there forever. You can move away, but it's a ton of work that reaches into every corner of your app. Other solutions, like serializing to a property list or SQLite, simply require a translation layer that you can switch out more or less at will.
Fourth, it's unbelievably slow. Literally unbelievable, as in I tell people about it and they don't believe me. It's too slow for a large number of records. It's fast enough for a very small number of records, but at that level it provides no advantage over using property lists and just loading everything into memory. At the large scale, you don't want to load everything into memory so you need a better scheme, but then you need something like SQLite so you can avoid the slowness and gain more control. Core Data is really only workable when your quantity of data is in a happy medium, which exists roughly within the range of 1097 to 1143 records. (Warning: previous numbers made up.) Since you can almost never guarantee that your data will live in that happy medium and not exceed it, Core Data is a bad choice.
I understand why its proponents advocate for it. It's shiny. Apple pushes it hard, and people tend to like what Apple tells them to like. It gives the illusion of making things easy. It does make certain simple things easy. The problem is that making easy things easier is not a virtue. Making difficult things easier is what counts, and Core Data fails at that.
[1] https://github.com/mneorr/ObjectiveRecord