Monday, April 4, 2011

CoreData != CoreObjects

I ran into a situation last week that had me (proverbially) tearing my hair out.

I was trying to call methods on an object stored using CoreData and the calls just WOULD NOT WORK. The reason was not obvious, and even the simplest method dispatch was failing: the debugger showed the objects as being of type NSManagedObject rather than the expected GTGItemLocationList, even after casting the local var as a (GTGItemLocationList *).

Managed object


Rather than continue, I decided to spend some time reading Pro Core Data for iOS since, in any case, I felt that my understanding of Core Data was suboptimal. Pro Core Data is an excellent resource and greatly improved  my understanding of the Core Data framework. I decided to stop trying to treat my GTGItemLocationList as an instance of the GTGItemLocationList class, and instead use the NSMutableArray pattern described in the book.

I  went back and coded up what I needed in about an hour.

Everything has been going well since then, and I thought I'd write this up as a cautionary tale about CoreData not providing objects in the manner expected. However, after digging a bit more, I found that this wasn't quite accurate. After all, the method which was throwing this exception was itself a method on an object stored by CoreData, and the dispatch was to the expected class/method combination. The pattern of accessing the object was different: rather than directly through an accessor, it was via an objectEnumerator on NSArray. The object returned using this technique was a GTGItem manipulatable via conventional OO techniques as expected (and appreciated).

Working item

I will admit that I haven't determined what's going on here. I think that the moral of the story is that in exchange for CoreData's simplicity and ease of use,* you might find yourself exploring a corner case that exhibits unexpected behavior. In retrospect, the GTGItemLocationList is completely superfluous. Eliminating this class would improve functionality and move me back into the CoreData's core use cases, reinforcing one of my basic iOS heuristics: If it is very hard to do, your first reaction should be "what built in function am I ignoring that would make this easy?".

For completeness -- I'm not the only one who has seen this problem, see here, and here -- none of the suggestions cured my problem


 *I mean this sincerely: the Pro Core Data highlighted the built in! CoreData data migration capabilities. Given how much time the industry spends planning/managing/performing data migration projects, any capability in this space is welcome.

No comments: