Originally created by @Koshub on GitHub (Apr 24, 2016).
Due the CoreData cache sometimes I have to call refreshAndMerge to refetch objects from persistaten store. Do we have an API to update objects directly with main context, not with child of main?
Originally created by @Koshub on GitHub (Apr 24, 2016).
Due the CoreData cache sometimes I have to call `refreshAndMerge` to refetch objects from persistaten store. Do we have an API to update objects directly with main context, not with child of main?
adam
added the question label 2025-12-29 15:23:06 +01:00
CoreStore's main context is strictly readonly. This was designed for performance and data integrity.
I suggest you use ListMonitor or ObjectMonitor; objects managed by NSFetchedResultsController automatically gets refreshed.
@JohnEstropia commented on GitHub (Apr 26, 2016):
CoreStore's main context is strictly readonly. This was designed for performance and data integrity.
I suggest you use ListMonitor or ObjectMonitor; objects managed by NSFetchedResultsController automatically gets refreshed.
Not sure your suggestion will resolve the issue. For example, I update Project entity and then after that immediately I try to load entity (FeedItem) with one-to-one relation of that Project and I receive unupdated object. Here is my code with comments where I have to put refresh calls:
funcupdateProject(project:Project){CoreStore.beginSynchronous{(transaction)->VoidinifletprojectModel=transaction.fetchOne(From(CDProject),Where("identifier == %@",project.identifier)){projectModel.updateWithProject(project)}transaction.commitAndWait()}}funcfeedItemWithId(id:String)->FeedItem?{ifletfeedItemModel=CoreStore.fetchOne(From(CDFeedItem),Where("identifier == %@",id)){// Need to call here feedItemModel.refreshAndMerge()varitem=FeedItemMapper.fromCDFeedItem(feedItemModel)ifletprojectModel=feedItemModel.project{// Need to call here projectModel.refreshAndMerge()item.project=ProjectMapper.fromCDProject(project:projectModel)}returnitem}else{returnnil}}
@Koshub commented on GitHub (Apr 26, 2016):
Not sure your suggestion will resolve the issue. For example, I update `Project` entity and then after that immediately I try to load entity (`FeedItem`) with one-to-one relation of that `Project` and I receive unupdated object. Here is my code with comments where I have to put refresh calls:
``` swift
func updateProject(project: Project) {
CoreStore.beginSynchronous { (transaction) -> Void in
if let projectModel = transaction.fetchOne(From(CDProject), Where("identifier == %@", project.identifier)) {
projectModel.updateWithProject(project)
}
transaction.commitAndWait()
}
}
func feedItemWithId(id: String) -> FeedItem? {
if let feedItemModel = CoreStore.fetchOne(From(CDFeedItem), Where("identifier == %@", id)) {
// Need to call here feedItemModel.refreshAndMerge()
var item = FeedItemMapper.fromCDFeedItem(feedItemModel)
if let projectModel = feedItemModel.project {
// Need to call here projectModel.refreshAndMerge()
item.project = ProjectMapper.fromCDProject(project: projectModel)
}
return item
} else {
return nil
}
}
```
This behaviour is NSManagedObject's caching mechanism and beyond CoreStore's control
(and thus the existence of refreshAndMerge() and refreshAsFault() methods.)
Like I mentioned, NSFetchedResultsController does this for free, but with the cost of constantly processing its objects. Otherwise, calling refreshAndMerge() like how you did is correct.
For the record, we can extend CoreStore to do this automatically all the time, but the performance cost may not be worth it.
@JohnEstropia commented on GitHub (Apr 27, 2016):
This behaviour is `NSManagedObject`'s caching mechanism and beyond CoreStore's control
(and thus the existence of `refreshAndMerge()` and `refreshAsFault()` methods.)
Like I mentioned, `NSFetchedResultsController` does this for free, but with the cost of constantly processing its objects. Otherwise, calling `refreshAndMerge()` like how you did is correct.
For the record, we can extend CoreStore to do this automatically all the time, but the performance cost may not be worth it.
Thank you for response. I can't use NSFetchedResultsController. I think if I have the API to update objects with main context, not child, I will fetch always correct objects. I understand that you need child context to implement amazing transactions logic. Also I understand that I can use main context through fetched managed objects. Although I think you have the other reasons to make main context readonly I will be very happy if you try to provide some API to interact directly with main context. Thank you for your time and excellent Pod library.
@Koshub commented on GitHub (Apr 27, 2016):
Thank you for response. I can't use `NSFetchedResultsController`. I think if I have the API to update objects with main context, not child, I will fetch always correct objects. I understand that you need child context to implement amazing transactions logic. Also I understand that I can use main context through fetched managed objects. Although I think you have the other reasons to make main context readonly I will be very happy if you try to provide some API to interact directly with main context. Thank you for your time and excellent Pod library.
Allowing updates to the main context objects means two things:
You are bypass all transactions, which breaks the deterministic order of updates.
You introduce a "non-saved" state in the main context. This is bad because 1) the main context's children (i.e. in transactions) will see a different snapshot of objects, and 2) you may be showing the User something that is not actually in the disk file yet.
CoreData's processing gets loaded to the main queue (which is the main context's queue). This introduces UI lags and the risk of deadlock.
So sorry, I prefer the main context the way it is. IMO it's a small price to pay for all the safety and guarantees that CoreStore offers.
@JohnEstropia commented on GitHub (Apr 28, 2016):
Allowing updates to the main context objects means two things:
1. You are bypass all transactions, which breaks the deterministic order of updates.
2. You introduce a "non-saved" state in the main context. This is bad because 1) the main context's children (i.e. in transactions) will see a different snapshot of objects, and 2) you may be showing the User something that is not actually in the disk file yet.
3. CoreData's processing gets loaded to the main queue (which is the main context's queue). This introduces UI lags and the risk of deadlock.
So sorry, I prefer the main context the way it is. IMO it's a small price to pay for all the safety and guarantees that CoreStore offers.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Originally created by @Koshub on GitHub (Apr 24, 2016).
Due the CoreData cache sometimes I have to call
refreshAndMergeto refetch objects from persistaten store. Do we have an API to update objects directly with main context, not with child of main?@JohnEstropia commented on GitHub (Apr 26, 2016):
CoreStore's main context is strictly readonly. This was designed for performance and data integrity.
I suggest you use ListMonitor or ObjectMonitor; objects managed by NSFetchedResultsController automatically gets refreshed.
@Koshub commented on GitHub (Apr 26, 2016):
Not sure your suggestion will resolve the issue. For example, I update
Projectentity and then after that immediately I try to load entity (FeedItem) with one-to-one relation of thatProjectand I receive unupdated object. Here is my code with comments where I have to put refresh calls:@JohnEstropia commented on GitHub (Apr 27, 2016):
This behaviour is
NSManagedObject's caching mechanism and beyond CoreStore's control(and thus the existence of
refreshAndMerge()andrefreshAsFault()methods.)Like I mentioned,
NSFetchedResultsControllerdoes this for free, but with the cost of constantly processing its objects. Otherwise, callingrefreshAndMerge()like how you did is correct.For the record, we can extend CoreStore to do this automatically all the time, but the performance cost may not be worth it.
@Koshub commented on GitHub (Apr 27, 2016):
Thank you for response. I can't use
NSFetchedResultsController. I think if I have the API to update objects with main context, not child, I will fetch always correct objects. I understand that you need child context to implement amazing transactions logic. Also I understand that I can use main context through fetched managed objects. Although I think you have the other reasons to make main context readonly I will be very happy if you try to provide some API to interact directly with main context. Thank you for your time and excellent Pod library.@JohnEstropia commented on GitHub (Apr 28, 2016):
Allowing updates to the main context objects means two things:
So sorry, I prefer the main context the way it is. IMO it's a small price to pay for all the safety and guarantees that CoreStore offers.
@Koshub commented on GitHub (Apr 28, 2016):
I see. I understand all these things. You are right. Thank you.