Yesterday I was coding a
UITableViewController for my third iPhone application and it all looked so simple as I just needed to retrieve some Core Data
NSManagedObjects and display them in a table. Unfortunately when I started testing my code I saw that the second row in my table was always empty, in spite of the fact that the Core Data repository contained two entities with all the necessary data to create objects of this class.
Basically I have two objects with a relationship:
| SSCategory | <<--------> | SSIcon |
| name | | name |
| subtitle | | file |
| ... | +--------+
SSCategory object has a one-to-one relationship with an
SSIcon object (named
icon), and an
SSIcon object has a one-to-many relationship with multiple
SSCategory objects (named
At first I thought the problem was in the Core Data repository itself, as I created some objects by hand using the excellent Core Data Editorcreated by Christian Kienle. I deleted the
.sqlite file and started from scratch but the problem was still there.
I did some research on the Core Data fault mechanism and found some questions in StackOverflow, but none of them were of help, so I tried something on my own and I think I found a plausible explanation, albeit not a very technical one.
In my code there’s a table to show a list of
SSCategory objects. When I fetch these objects from the repository I get an array with two faulted entities, which means they are empty objects:
<SSCategory: 0xb879610> (entity: SSCategory; id: 0xb87a1a0 <x-coredata://407108B7-288F-437B-B6F7-A3D65552D45C/SSCategory/p1> ; data: <fault>),
<SSCategory: 0xb87bed0> (entity: SSCategory; id: 0xb878c30 <x-coredata://407108B7-288F-437B-B6F7-A3D65552D45C/SSCategory/p2> ; data: <fault>)
Then, when the table is being populated with some of the
SSCategory properties (like
subtitle), the Core Data mechanism automatically retrieves the data and voilà, all the table rows show the right info.
When I need to create a new
SSCategory object I must assign it a suitable
SSIcon object which can be selected from another table, so I followed the same logic as before to create and load data for this table: I fetch all the SSIcon entities in the Core Data repository by themselves. This time in the populated table I saw two rows (as expected) but only the first one had data on it, the second one was blank.
Upon closer inspection I found that when fetching these
SSIcon objects, only the first one had data, and the second one was always at fault, so nothing was retrieved from the repository and consequently the table row for this object didn’t have any info on it.
I looked for a way to force these objects to load their data, but it seems Core Data doesn’t provide a way to do this, as this behavior is automatic. Then I remembered I was only loading a single property of the
SSCategory objects, i.e. its
name instance variable, as I was leaving out other properties for later, since I don’t have all the icon images that I’m planning to use, for example. So what I did was to also load the
SSIcon objects by accessing the related property (
icon) and this time the icon list showed all the data, since the faults were fulfilled at a previous stage, namely when loading their owning SSCategory objects.
Now, the explanation I came up with is simply that at first when I was trying to fetch all the
SSIcon objects on their own, the faults weren’t being fulfilled as they should be automatically fired when the related property of the owning object – in this case, an
SSCategory instance – is called. As the second SSIcon entity isn’t yet called by any SSCategory entity, it remains at fault for the whole lifetime of the application.
Hope this makes sense. In any case, the right approach is to access all the pertinent parent object’s properties and then the child object’s data will be automatically loaded.