views:

40

answers:

3

Let's say we have two objects.

Furthermore, let's assume that they really have no reason to exist without each other. So we aren't too worried about re-usability.

Is there anything wrong with them "knowing about" each other? Meaning, can each one have the other as a property?

Is it OK to do something like this in a mythical third class:

Foo *f = [[Foo alloc] init];
self.foo = f;
[f release];

Bar *b = [[Bar alloc] init];
self.bar = b;
[b release];

foo.bar = bar;
bar.foo = foo;

...so that they can then call methods on each other? Instead of doing this, I'm usually using messaging, etc., but sometimes this seems like it might be a tidier solution.

I hardly ever see it in example code (maybe never), so I've shied away from doing it. Can somebody set me straight on this? Thanks.

+1  A: 

If you need a pattern like this, the likelyhood is that the two classes of the two objects should be merged; or that whatever part of them messages one another should be moved out into your mythical third class.

Williham Totland
This did in fact turn out to be the case, Williham. I ended up realizing that these two classes really needed to be one class.
mwt
+1  A: 

Yes there is a problem with them knowing about each other like that. You will likely create a retain cycle unless you remember to clear the foo or bar property of the other before sending the final release message to either f or b. If anyone else can get access to these variables then you will likely have no idea when this final release is being sent, and so you will leak memory with the retain cycle.

Example:

Mysterious init:
Foo * f = [[Foo alloc] init];  // Foo retain is 1
self.foo = f;                  // Foo retain is 2
[f release];                   // Foo retain is 1

Bar * b = [[Bar alloc] init];  // Bar retain is 1
self.bar = b;                  // Bar retain is 2
[b release];                   // bar retain is 1

self.foo.bar = self.bar;       // Bar retain is 2
self.bar.foo = self.foo;       // Foo retain is 2

Mysterious dealloc:
self.foo = nil;  // Foo retain is 1
self.bar = nil;  // Bar retain is 1
// Foo and Bar are now leaked.

Instead look into delegation if you need to be able to send messages to each other. Cocoa Fundamentals Guide: Delegates and Data Sources

Brandon Bodnár
Correct me if I'm wrong, but what you're saying would only be true if I put a "retain" command in the @property declaration, No?
mwt
Either retain or copy will cause the issue. No problem with retain cycle if you just use assign. But I still think what you are looking for is very much related to the delegation pattern that is used all over the place by Cocoa
Brandon Bodnár
This is not a problem with Garbage Collected applications though?
rebo
@rebo. No, retain cycles are not a problem with GC applications due to how the GC works. But mwt normally asks iPhone related questions, so I don't think the GC is involved here
Brandon Bodnár
Correction to an earlier comment. You don't get retain cycles with copy under normal cases.
Brandon Bodnár
Correct, I'm talking about a Cocoa Touch app.
mwt
+1  A: 

This is a common pattern, where a controller knows the view it controls and the view delegates operations to its controller.

mouviciel