Mastering In CoreData (Part 13 Multithreading Concurrency Strategy Notifications)
There are two popular strategies that Core Data supports, notifications and parent-child managed object contexts. In this part we will look Notificationsonly .This strategy is not recommended by apple so we will not doing in depth.
Types Of Notifications
Managed Object Context posts three types of notifications to notify objects of changes taking place in a Managed Object Context
NSManagedObjectContextObjectsDidChangeNotification: This notification is posted when one of the managed objects of the managed object context has changed
Note: These notification will only post when you call save() method on the context. When you call save() method WillSaveNotification and NDidSaveNotification notifications will surely call and the DidChangeNotification only calls when you actually done some changes in the context.
When a Managed Object Context save its changes to a Persistent Store, via the persistent store coordinator, other managed object contexts may want to know about those changes. This is very easy to do and it’s even easier to include or merge the changes into another managed object context.
Note : These notification will not fire if you are doing NSBatchUpdateRequest/NSBatchDeleteRequest (Ignore for now )
Handling Notifications
Download the starter project here and if you you have already delete the application first
We can observe these notifications by adding an observer to NotificationCenter As shown in Figure 1
As you can see in Figure 2 we handled DidChangeNotification only . The notifications are just half of the whole story. As you can see all observersmethod are passed by notification object. Notification object has a userInfoinstance property that holds all the information in a Dictionary. These are all the keys that are used to retrieve the changed data
NSUpdatedObjectsKey key contains all the NSManagedObject updated.
NSInsertedObjectsKey key contains all the NSManagedObjectinserted.
NSDeletedObjectsKey key contains all the NSManagedObject deleted.
NSRefreshedObjectsKey key contains all the NSManagedObject refreshed.
Insert Case
As you can see we inserted User object in Figure 3 . Notification will fire when save() method executed
As you can see in Figure 4 since we inserted object in Figure 3 which means there is a change in the context first DidChangeNotification will fire and we handled this that’s why in the console it is printed that we inserted object.
After that WillSaveNotification and DidSaveNotification notification will fire sequentially and since we didn’t do anything in their selector method nothing will going to happen. As shown in Figure 4 User that we inserted in Figure 3 is printed on the console .
领英推荐
Update case
As shown in Figure 5 we fetched the User object we just inserted in previous section and update it’s value when we call save() method Notification handler printed the Updated value. We accomplished this by doing following actions
We will not do delete. You can trust it will work. Now the question is we notified what is updated, inserted and deleted but how can we merged or update other context as well . In the next section we will going to do this
Merges Changes to Another Context
As we saw in part 12 we encountered concurrency problem in which one context was doing some heavy task in the background thread and other is dealing with UI related work but both are unaware of the work status Weather it is done or not and we saw that one context saves data into the persistent store and other used older value which caused a problem. So in this section we will look how notification can solve this problem and merged updated value to other context when one is done with their task. In short how one context update other context with the changes that is done by that.
Let’s suppose we have two managed Object Context we called Managed Object Context A and Managed Object Context B both request User data from the persistent store as shown in Figure 6. User Entity has firstName and secondName properties.
Managed Object Context B private context that is processing server data
Managed Object Context A representing UI data main Thread
As shown in Figure 7 Managed Object Context B updated firstName value from the data that comes from server and pushed that changes to persistent Store Coordinator to Persistent Store using save method on the context. Managed Object Context A doesn’t know that changes still and have older value which is a problem
As shown in figure 8 if we are handling notification as discussed in previous section we can observed to the NSManagedObjectContextDidSave notification now when save action was done NSManagedObjectContextDidSave selector will be executed and we can call mergeChanges method which will update ManagedObjectContextA so using notifications of the context we can solve this problem.
Now both context will have same state. There can be chances that while merging conflict occurs and we will discuss these conflict later.
Now let's dive into the coding parts and proved it using code but before start first delete the application. We added user object and save it to the persistent store as shown in in Figure 7 .
When private context update value we just inserted , using notification we merged that changes to main context as well and you can see on the console in the Figure 9 . We accomplished this after performing number of tasks
Note: When we call mergeChanges method there might be a chance that conflict occurs, for that we need to create merge policy and we will discuss this in the upcoming parts .
Disadvantages
Summary
In this part 13 we solved the concurrency problem using Notification that Core data provides