In the CoreData Apple Docs on working in the background, I came across this bit of advice:
For example, you can configure a fetch request to return just object IDs but also include the row data (and update the row cache)—this can be useful if you're just going to pass those object IDs from a background thread to another thread.
I was wondering how you might implement this fetch request? Specifically how to update the row cache.
I think this is how get just the IDs:
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"MyItem"]; // iOS 5 method
request.returnsObjectsAsFaults = YES;
How do I do the rest?
By default, includesPropertyValues is YES, and returnsObjectsAsFaults is also YES.
If you just want to return object IDs, you need to use...
fetchRequest.resultType = NSManagedObjectIDResultType;
However, there are no properties to be fetched, and the row cache will not be populated. You will just get back a bunch of object IDs.
Note, that BY DEFAULT, (resultType == NSManagedObjectResultType), since both includesPropertyValues and returnsObjectsAsFaults are YES, a fetch will return objects as faults (the object ID is accessible), and the row cache will be filled - but the data will not truly be "in memory" because the object is still a fault... but you can still get at its object ID.
All you need to do is then ask the object for its objectID.
All that, I guess, to say that the behavior you are asking for is what you get by default. So, are you having a problem, or is there some reason you think you are NOT getting that behavior?
EDIT
Ummm... I am saying that BY DEFAULT, you are getting what you want. If you just fill out a fetch request, and don't change any of the attributes, returnsObjectsAsFaults is YES -- so objects that are returned to you will be faults. Furthermore, includesPropertyValues is also YES -- so some amount of property data will be available in the row cache.
You can access the objectID property by calling, well, managedObject.objectID.
EDIT
I apologize, because I am obviously not doing a very good job of communicating because this will be the third time I've said the same thing.
When you create a NSFetchRequest, it has several properties that are set by default.
resultType is set to NSManagedObjectResultType by default. That means, unless you change it, it will still be NSManagedObjectResultType. It also means that the array of results that you get from a fetch will contain an array of NSManagedObjects (as opposed to getting back a count, or a dictionary, or ObjectIDs).
returnsObjectsAsFaults is set to YES by default. That means, unless you change it, it will still be YES. It also means that objects that get returned from a fetch will be faults. The NSManagedObject will not be realized with property data. The object will be a fault. It will have enough metadata to know its type, object ID, and some other stuff.
includesPropertyValues is set to YES by default. That means, unless you change it, it will still be YES. It also means that some amount of property data will be fetched into the row cache.
Each NSManagedObject that gets returned from the fetch will:
- Have an Object ID
- Be a fault, so the data isn't actually loaded fully into memory
- Some amount of property data will be in the row cache
This is everything you are asking for. I'm not sure what else I can add (without repeating myself yet again).
Also, note that if you just want object IDs you can set resultType to NSManagedObjectIDResultType.
Directly from the NSFetchRequest documentation...
includesPropertyValues
You can set includesPropertyValues to NO to reduce memory overhead by
avoiding creation of objects to represent the property values. You
should typically only do so, however, if you are sure that either you
will not need the actual property data or you already have the
information in the row cache, otherwise you will incur multiple trips
to the database.
During a normal fetch (includesPropertyValues is YES), Core Data
fetches the object ID and property data for the matching records,
fills the row cache with the information, and returns managed object
as faults (see returnsObjectsAsFaults). These faults are managed
objects, but all of their property data still resides in the row cache
until the fault is fired. When the fault is fired, Core Data retrieves
the data from the row cache—there is no need to go back to the
database.
If includesPropertyValues is NO, then Core Data fetches only the
object ID information for the matching records—it does not populate
the row cache. Core Data still returns managed objects since it only
needs managed object IDs to create faults. However, if you
subsequently fire the fault, Core Data looks in the (empty) row cache,
doesn't find any data, and then goes back to the store a second time
for the data.
and...
returnsObjectsAsFaults
The default value is YES. This setting is not used if the result type
(see resultType) is NSManagedObjectIDResultType, as object IDs do not
have property values. You can set returnsObjectsAsFaults to NO to gain
a performance benefit if you know you will need to access the property
values from the returned objects.
By default, when you execute a fetch returnsObjectsAsFaults is YES;
Core Data fetches the object data for the matching records, fills the
row cache with the information, and returns managed object as faults.
These faults are managed objects, but all of their property data
resides in the row cache until the fault is fired. When the fault is
fired, Core Data retrieves the data from the row cache. Although the
overhead for this operation is small, for large datasets it may become
non-trivial. If you need to access the property values from the
returned objects (for example, if you iterate over all the objects to
calculate the average value of a particular attribute), then it is
more efficient to set returnsObjectsAsFaults to NO to avoid the
additional overhead.
Let me explain it the easy way
By default, NSFetchRequest
has
resultType: NSManagedObjectResultType
returnsObjectsAsFaults: YES
includesPropertyValues: YES
Here the return object (in memory) only has objectID
property, all other properties is empty (This is what called fault)
includesPropertyValues
YES: means the object properties is in the row cache (some special
cache of CoreData), so that when you access those properties, CoreData
will look for them in the row cache
NO: means there's no row cache, when you access those properties,
CoreData will query SQLite again
returnsObjectsAsFaults
YES: allow includesPropertyValues to have effect (means allowing faulting)
NO: return the object wilh all its properties in memory
NOTE: there are 2 kinds of fault : managed object fault and relationship fault
Read more here Faulting Limits the Size of the Object Graph
So in your case, just play with the default