Re: class design issue
Re: class design issue
- Subject: Re: class design issue
- From: email@hidden
- Date: Wed, 30 Jan 2002 00:27:58 -0800
The real problem occurs for me when the BookController needs to call
some method on the MainController instance. BookController has no
pointer to the MainController, and neither does the Book instance it
references. In other similar cases, I solved the problem by making the
class in question a singleton with a class method that instantiated the
static instance and returned it so i could call methods on it. However,
in this case, the class was loaded from MainMenu.nib and I can't get a
global handle on it.
I will admit at the outset, I skimmed the detailed description of your
class hierarchy and focussed on this part, since this seems to be at the
root of your problem.
Just because your MainController class is instantiated from a nib
doesn't mean you can't have a global handle to it. I do this all the
time. You want something like (I'm typing this into my e-mail, so
forgive any minor hiccups... hic!... :->):
static MainController *sharedMainController = nil;
@interface MainController
+ (MainController *)sharedController;
@end
@implementation MainController
+ (MainController *)sharedController
{
// If our shared controller isn't around yet,
// instantiate ourselves to fill the global.
if (!sharedMainController)
[[MainController alloc] init];
return sharedMainController;
}
- init
{
if (self = [super init])
{
// Do our init. This can be skipped (as
// well as the call to [super init]) when we
// already have a shared object, *if* it is
// safe for release and dealloc to be called
// without it.
...
// If we already have a shared object,
// bail on self and return it instead.
if (sharedMainController)
{
self = [super init];
[self release];
return sharedMainController;
}
else
{
sharedMainController = [self retain];
}
}
return self;
}
@end
You can see this pattern all over AppKit and Foundation. It will work
with objects instantiated from a nib, because -init checks the global
and fills it in with self. There are various ways to do it, but this is
how I usually do it. The interception of a second creation in -init is
a little gross, and I suppose you could achieve the same thing more
gracefully by overriding +alloc or something, but... this is how I do
it. :-> If you know for sure that a second attempt to instantiate the
class will never occur, then you can log and leave it at that -- delete
the gross interception code. That's what I really usually do. :->
Ben Haller
Stick Software