开发者

NSFetchedResultsController does anyone have any insights into the cache implementation?

开发者 https://www.devze.com 2023-02-01 06:10 出处:网络
this is a bit of an odd question, so I\'ll start at the beginning... My needs for NSFetchedResultsController (NSFRC) are the ability to perform filtering and sorting after the objects have been fetch

this is a bit of an odd question, so I'll start at the beginning...

My needs for NSFetchedResultsController (NSFRC) are the ability to perform filtering and sorting after the objects have been fetched, mostly because the filtering and sorting require querying the fetched objects themselves, and is therefore not possible with NSFRC. So, I wrote my own class, BSFetchedResultsController, which aims to replicate the functionality of NSFRC (delegate notifications, automatic sectioning and caching) but with added hooks for the user to set their own blocks for filtering and sorting. The code for this 开发者_如何学JAVAclass is on github here if anyone wants it: https://github.com/blindingskies/BSFetchedResultsController, although I wouldn't consider the class ready yet as a drop in replacement of NSFRC.

So, I've not yet implementing caching, mostly because I'm not really sure how Apple has implemented it. The caches are stored in binary files here:

{app dir}/Library/Caches/.CoreDataCaches/SectionInfoCaches/{cache name}/sectionInfo

So, presumably, my class would need to store its caches in a similar location? How is this structure organised/work? The cache needs to store the NSFetchPredicate (or properties required to re-generate it), and it needs to archive the fetched objects somehow. But, NSManagedObject doesn't conform to NSCoding, so, how does it archive the objects? And lastly during the NSNotificationCenterDidChangeNotification handler the cache needs to be updated.

So, the real aspect of this is how to archive the fetched objects, I'm leaning towards just saving the objectIDs in an array? And then just get those objects from the context. Is that enough?

If anyone has thought about how to implement


Okay, so to answer my own question, I've implemented the cache as follows:

Created another class which retains the entity (NSEntityDescription), fetch predicate (NSPredicate) and sort descriptors (NSArray) of the NSFetchPredicate, along with the sectionNameKeyPath and additional BSFetchedResultsController objects (post fetch predicate, filter, comparator). Make this class NSCoding compliant.

Then at the start of the performFetch: method, if there is a cache name, unarchive the object and see if the properties match the BSFRC, and if it does, then use the cache's section data.

Then add another notification handler, to NSManagedObjectContextDidSaveNotification to flush the objects to the cache.

A couple of points... I found that archiving the NSFetchRequest directly (which is NSCoding compliant) didn't work, and at the moment, am only checking the name of the NSEntityDescription.

Also, I don't cache the whole object graph, just the URIRepresentation of the NSManagedObject's NSManangedObjectIDs. Then, I respawn these URIs given the managed object context after validating the cache.

It seems to work, although I'm not sure how often I should flush the objects to the cache...

0

精彩评论

暂无评论...
验证码 换一张
取 消