That's perfect, easy to understand, and it works too. You're an excellent teacher - and my apologies for not knowing the correct terms. I'm more used to plain old C (but I try to better myself).

On a related note, how does this relate to plugin bundles? I've created a plugin (using the tutorial in Aaron Hillegass's excellent book) - and it works perfectly. I want to be able to respond to events in the plugin though - would IBAction be the best way to do this since there doesn't seem to be a way of getting the App to be a delegate for one of its plugins?


On 6 Aug 2010, at 02:04, Graham Cox wrote:


On 06/08/2010, at 1:36 AM, Geoffrey Holden wrote:

So, the header for Foo contains

Bar* bar;

And when Foo is initialised it contains:

bar = [[Bar alloc] init];

And now I'd like to be able to call Wabble in Foo from a function within bar (I realise that this seems to be going the wrong way along the hierarchy).

Bar doesn't have any particular reference to Foo other than that Foo called it - unless ObjC provides such a reference for free.

Thanks for your help.


No, you don't get this for free. And you need to be careful about proper memory management and clear lines of ownership.

Foo owns Bar. Bar needs a pointer to Foo. As Foo is responsible for instantiating <bar> (it owns it), then it can also set the pointer back to itself (what I typically call "back pointers"). This should be done through an accessor (e.g. -setFoo:) or perhaps a parameter to the designated initializer, e.g.:

//Foo:

bar = [[Bar alloc] initWithFoo:self];

//Bar:

- (id) initWithFoo:(id) foo
{
   self = [super init];
   if( self )
   {
m_FooRef = foo; // m_FooRef is the ivar "back pointer", does not retain <foo>
   }

   return self;
}

This is commonly done, or you could make the ivar m_Foo an IBOutlet and connect it in IB if <bar> is an object in the nib. There are a few things to be aware of when you create these references. First if Foo retains <bar> then Bar shouldn't retain <foo>. That's a retain cycle and would prevent either object from being released, and so leak memory (unless you're using Garbage Collection, where that isn't an issue). My usual convention for ivars that reference but do not retain objects is to use the suffix Ref, as above. That's just a reminder to me about the ivar's function, it doesn't cause any magic to happen.

Anyone else could also retain <bar>, so when <foo> is dealloc'ed, and releases <bar>, bar might not actually be deallocated at that time, meaning that it now has a stale reference to <foo>. So even if the logic suggests that the two things will be deallocated together, you need to remove the reference to <foo> from <bar> at that time - following a stale reference will cause a crash.

//Foo:

- (void)    dealloc
{
[bar setFoo:nil]; // remove back pointer to this as we are about to disappear [bar release]; // release bar - might not deallocate it if someone else is retaining it
   [super dealloc];
}


Review of the general documentation on memory management and object ownership are a vital read, and should help you get all this clear.


--Graham

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to