Question

Suppose I have this:

@interface ThingManager : NSObject
@property Thing *aThing;
@end

Is there a way for aThing to know at runtime that it is a property of ThingManager?

Was it helpful?

Solution

You start with the question:

Is there a way for aThing to know at runtime that it is a property of ThingManager?

Though not completely clear the answers so far have assumed you want aThing to be able to determine whether an instance of ThingManger is managing it.

So at this point we know that the ThingManger class knows about the Thing class, and you now appear to want the reverse - you ask can a Thing find its ThingManager?

However when someone answers that you comment

So Thing and ThingManager need to know about each other? Mmmm... Bad for loose coupling.

Hmmm... How can a Thing ask what its ThingManager is if you don't want it to know about ThingManagers?

Is everybody's interpretation of your question wrong?

Maybe you are concerned not about loose coupling but about strong reference cycles? If the two know about each other, and create a strong cycle in doing so, then there is a risk they will keep each other alive long after the need for either by your application - is that the concern?

But that is addressed by @DrummerB - you use a weak property on Thing which references its managing ThingManager. So it would appear that strong reference cycles are not your concern either...

Then you comment:

Isn't there a way to see who's referencing an object at runtime?

As stated generally that is a very different question. The short answer to this is no[*].

Are you asking whether it is possible to write a method which a Thing can call to find the ThingManager that is managing it without any references being maintained between Thing instances and ThingManager instances?

If so here is an outline algorithm:

  1. Have the ThingManager class keep a collection of all create and alive instances of itself. The alive requirement requires this collection be some kind of weak collection (design your own or do a search for weak collections).
  2. Add a class method to ThingManager which finds the manager for a Thing, e.g. something like + (ThingManager *) managerFor:(Thing *)thing.
  3. Have your Thing instances call [ThingManager managerFor:self] when they need to know their manager.

That of course doesn't address your concern over loose coupling - the two classes must still know of each others existence...

Which brings you back to the direct solution of having Thing have a manager property. If you want to reduce the coupling you can type this property as id, so its any old object, or id<SomeMinimalManagerProtocol> so its any old object provide it implements some minimal set of management methods you've define in the protocol SomeMinimalManagerProtocol.

Take a look at NSWindow and NSWindowController - they know about each other.

HTH


[*] The long answer is that (Objective-)C(++) are not designed to ensure all references can be found. This is why you hear phrases such as "conservative garbage collection". There was a garbage collector for just Objective-C objects, which was supported by internal changes to the runtime, but that is now deprecated and its machinery wasn't easily accessible to applications to apply to other uses.

OTHER TIPS

Not unless you tell it, that it is.

You could add a ThingManager weak property to Thing and implement the setter in ThingManager like this:

- (void)setAThing:(Thing *)thing {
    if (_aThing != thing) {
        _aThing = thing;
        _aThing.manager = self;   // this is the relevant line
    }
}

Not unless you have a custom setter for your aThing property that sets something on the Thing object to tell it that it is. You could have the aThing setter method set a property that you add to Thing that tells it who its manager is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top