Re: calling a function in one class from another
Re: calling a function in one class from another
- Subject: Re: calling a function in one class from another
- From: Geoffrey Holden <email@hidden>
- Date: Mon, 9 Aug 2010 22:13:05 +0100
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 (email@hidden)
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:
This email sent to email@hidden