views:

21

answers:

1

I am a great fan of code generation (from UML) and coming from the Java world, I wonder how I would implement automated bi-directional association management in Objective-C.

Image an association Partner <-> Address, one-to-many and navigable from both ends. What I would like to achieve is that if I append an Address to a Partner that Address object should automatically know about its Partner.

So the implementation pattern would be to have an NSMutableArray* on the Partner side and a Partner* on the Address side. The property on the Address side is easy to implement, as a setPartner:(Partner*)aPartner could automatically insert the Address (self) into the Partner's NSMutableArray managing the addresses. The other side, however, is not so easy to implement. The standard implementation pattern for to-many references in Objective-C seems to be the NSMutableArray obtainable via the get method of the @property. The object in possession of this NSMutableArray could then insert an Address object into the array, which would of course not be updating the other side.

I know that there are other patterns for this kind of association management, for instance, via addTo...() and removeFrom...() methods. But I don't know yet if this would fit with other principles of Cocoa programming or even prevent me from using Cocoa efficiently. I am thinking about Interface Builder here. Not much experience, but I have seen something called an ArrayController which seems to be quite handy but which also seems to expect an NSMutableArray type property to work with. And if this guy inserts objects into the array I need to intercept that and make the other side adjustment.

As a Java programmer I would tend to subclass NSMutableArray now and override some of its methods which could then manipulate the other end. Would this be possible at all? I read about categories but so far I have understood that I could only add methods to a class this way and not override them nor add to the structure of it. Or should it be method forwarding? I am confused right now. If you could point me into the right direction of thinking it would be so great. Thanks a lot!

+4  A: 

Welcome to Cocoa. Do not subclass built-in collections. You will go insane.

Allow me to clarify: in Cocoa, we have these things called "Class Clusters". Clusters are a hierarchy of private classes that all have a common, public superclass. In this case, NSArray is the public superclass, and there are private subclasses that are the actual array implementations. This presents a really difficult challenge when subclassing, because you don't know what class (or classes) you would need to subclass.

The common work-around is to create a new NSObject subclass that "wraps" an NSArray (ie, it has the array as an instance variable ["field"]), and then you invoke methods on the custom wrapper, and the wrapper holds all the custom logic you need.

As to answer your question, I've found that when I have this sort of set up where I need to maintain one-to-one, one-to-many, or many-to-many relationships automatically, there's nothing that beats using CoreData. CoreData is a built-in framework that's more or less like an object store. One of the truly awesome things that it does is handle relationship integrity, which is what you're looking for.

Dave DeLong
Dave, thank you for saving me from learning it the hard way - I swear I will never ever even think about extending the collection classes again ;) I will have a closer look on CoreData now. It doesn't seem to support inheritance but for most parts of my data models that will be ok. I hope it can handle larger amounts of data (in binary form). Thanks again!
Andre Pareis
already found out that it can do inheritance. perfect!!!
Andre Pareis