The first edition of Core Data by Marcus Zarra was the book I turned to when I wanted to learn Core Data. Whilst it is still a great book it was. Threading in today’s Core Data is radically different from its original In this talk from #Pragma Conference , Marcus Zarra presents the. Core Data in Swift. by Marcus S. Zarra. Publisher: Pragmatic Bookshelf. Release Date: June ISBN: View table of contents. Start reading.
|Published (Last):||7 March 2012|
|PDF File Size:||7.42 Mb|
|ePub File Size:||1.61 Mb|
|Price:||Free* [*Free Regsitration Required]|
This talk was delivered live in October at Pragma Conference. The video was transcribed by Realm and is published here with the permission of the conference organizers. The long history of Core Data has lent itself to different interpretations over the years about how threading should be used, so how should it be done now? The goal of this post is to clear the air about how we should be using Core Data as it stands today, in Eleven years is zaarra a long time for a framework, especially today with the mobile aspect.
One of the problems with dealing with a framework that old is that there are eleven years of blogs and articles talking about Core Data, some of which are no longer accurate. The answer usually revolves around a performance problem. However, using threading to fix a performance problem tends to create two, four, eight, or twelve more performance problems. Threading is not a silver bullet. Adding threads to an application is a design decision, dwta if we make that decision at the 11th hour before shipping, we picked the wrong time.
Threading is something we add to an application when we find we have spare time, CPU, and bandwidth. We could even perhaps be caching avatars, or grabbing search results.
The user should not really have to wait for that network call to come back. You will wait and I will tell you if that tweet posted or not.
Threading should be solving those poor user experiences. The user interface is our truth. Mqrcus develop user-facing applications now, instead of applications sitting on a mainframe. The user is the one that should be getting the truth at all times.
Core Data in Swift [Book]
Therefore, we should have a context dedicated to azrra user and dedicated to giving them the truth. All user interfaces are single threaded. If the UI is single threaded, then we should be accessing the UI from a single source of truth.
Get off of it. Doing just these three things will solve most performance problems with Core Data. Apple programming frameworks did a fairly massive concept shift around iOS 5.
It had, in my opinion, a lot to do with the huge influx of developers that we got. Before iOS, and before the iPhone was ever public in any way, you could probably count the number of Objective-C developers on one hand. We were all on the same mailing list, we all knew each other, and we generally knew amrcus developers inside of Apple.
Then you would discuss it solve the problem because it was such a small tight-knit community.
Core Data in Swift
Threading was like that too; the threading rules were unclear, with different answers from different people.
It was still new technology. From toI think we went from 10, to half a million developers. When you release, it decrements it by one. When it hit zero, it goes away, and if you go to negative one, it crashes.
So, Apple had to do a paradigm shift in how they were approaching the frameworks and APIs. One of those was around threading, because threading is really, really hard.
We all get it wrong, even developers inside of Apple. The paradigm shift revolved around using queues instead of threads. Queues are fascinating because they work exactly the same as threads, except for when we write our code wrong, and they protect us from ourselves, which is cool.
In iOS 5, Core Data made a change. It was flaky and a little unstable. PSC handles all the interactions to disk. We use just one for the application. This was problematic hen we wanted to let one context know that we made a change in another context, probably on another thread.
We had to handle that through the notification system because every time you made a change to a MOC, it would then broadcast a notification that we had to consume and hand off to the other context. We had to do this correctly. This became a bit of a problem, because this was a system that was refined over a couple of years.
As Core Data first came out, everybody was like just figuring it out on their own.
Then, more and more defined rules developed over the years, but they were still confusing. In this system, we always had one single source of truth for the user interface: User interface is not going to come from any other thread, because the user interface is marcuss threaded.
The issue with this design is the large amount of code. The old complaints about Core Data being difficult daya use and having a tremendous amount of boilerplate code came from this era and this design.
You would, by the ckre of your application, have Core Data littered everywhere inside of your app. The threading rules were also unclear. The threading rules were a mess. We had no way to confirm or deny whether we got a threading rule right. You could easily imagine severe arguments during code reviews.
Who really knows until it crashes?
Maybe someone was listening to a notification on another thread, and they were trying to consume it on the wrong thread, or their UI was doing something bizarre and causing the entire app to halt. You end up littering your application with NSLogs to hopefully try to capture this so you can figure out exactly how you got to that locking point.
Core Data by Marcus Zarra
When you start listening to notifications, they get chatty. If you start, you tend to get a little bit overanxious and start listening to the notifications all over datz place. The good news is that this has gotten better in iOS 9. We have a debug flag marcuss that allows us to at least confirm that we got the threading right. We are now able to at least confirm if we got our threading right or wrong. SQLite is the persistence level we tend to use all the time.
We can have multiple threads talking to it at the same time. We can happily be pushing data in marvus one direction and consuming data from another direction. The good news is that we can dsta super, super close to that true asynchronous. We always still want to have one that exists on the thread, associated with the user interface. The context could at least query it or get some information from them. We can get out of sync with our data fairly easily. Notifications are also quite hard in this system.
This has changed a bit in iOS 9, where they added a new feature to allow us to consume remote notifications. We have to do a bit more dancing to get that right. Threading is even trickier than the first version.
Datq is just out the window. Marcux would we want to do this though? With our glances, there are reasons why we would want multiple applications talking to the same SQLite cre. You can understand why it took a few years for iCloud to become really nice and stable.
Object-oriented programming is slow. If you need the fastest, you need to be working with C or something even lower like SQLite. Generally, fastest is going to be some of the ugliest, nastiest code on the planet. It is code that I can look at with a cup of corre, and understand it before I finish the cup of coffee.
It is consumable code, where I can trace the bug without having to use a whiteboard. If debugging is that hard, why would we ever want to write code at the edge of our ability? I have to start all over again.
Any data processing will be below the main MOC, so we will have three levels of contexts. Our main has not changed. This design allows us to have asynchronous saves, which is extremely important.
It allows us to save and to consume or process data without blocking the UI. We have an extra level of indirection between the PSC and the main MOC, so we will get a little bit of slowness there.
But technically, yes, it is slower. It can also be more code. I have run into situations where people get really excited about blocks. They use blocks to an interesting new level. I have seen persistence layers where they have 12, lines of code in one class because everything can go into a block. They can be messy that way.
It can be more code only because it tempts us.