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 NSManagedObject
s 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 |
| ... | +--------+
+------------+
An 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 category
).
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:
<_PFArray 0xb87bfb0>(
<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 name
or 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.
Keep coding!