Re: Newbie question: how to release an object that has been autoreleased
Re: Newbie question: how to release an object that has been autoreleased
- Subject: Re: Newbie question: how to release an object that has been autoreleased
- From: Glenn Andreas <email@hidden>
- Date: Wed, 22 Sep 2004 17:05:55 -0500
At 12:43 PM -0700 9/22/04, James Bucanek wrote:
Glenn Andreas wrote on Wednesday, September 22, 2004:
This isn't all that different than the way a class cluster is
designed, and works because "init" can return something other than
"self". Thus there isn't a need to have a factory method to decide
what to do - this logic can be pushed into the init method itself.
<clip>
By doing this, you avoid the "newBufferNotAutoreleased" method - if
you don't want to create an autoreleased object, [[Buffer alloc]
init] will work just fine.
Except for the one important detail which I pointed out in my
earlier post: All of the details which Buffer would need to
initialize itself are @private or @protected instance variables in
BufferPool.
Having the BufferPool produce Buffer objects was a matter of
encapsulation. For Buffer to initialize itself will require me to
expose all (or at least some) of the private data of BufferPool to
the world. At the very least, I'd have to pass BufferPool to Buffer
([[Buffer alloc] initWithPool:pool]).
In general, I avoid any class that can't have objects created by
[[Foo alloc] init...] (or perhaps a convience function [Foo
fooWith...]) - after all, this is still going to be possible (and the
compiler isn't going to warn you if you or somebody else later on
accidentally does this), but the results will probably be something
very inconsistent. It also just seems wrong to have to ask a
different object/class to create it. I'd expect all the logic about
how and when and what subclass of Buffer to belong to the Buffer
class (though it may well ask an instance of BufferPool questions to
help determine what kind of buffer to alloc)
You could still hide away all this with something like:
@implementation Buffer
- (id) initFromPool: (BufferPool *)pool
{
[self release];
self = [[[pool bestClassForBuffer] alloc] init];
return self;
}
- (id) init
{
// use the "default pool" if not specified
if ([self class] == [Buffer class]) {
// anything done via [[Buffer alloc] init] goes through here
return [self initFromPool: [BufferPool defaultPool]];
} else {
// if a subclass of Buffer does [super init] we go through here
self = [super init];
if (self) {
// set up whatever ivars
}
return self;
}
}
@end
@implementation BufferPool
- (Class) bestClassForBuffer
{
if (needs a local buffer)
return [LocalBuffer class];
else if (needs shared buffer)
return [SharedBuffer class];
else if (needs remote buffer)
return [RemoteBuffer class];
else
return [PrivateBuffer class];
}
@end
You may already even have different subclasses of BufferPool for
different cases and just return appropriate classes. You could also
provide getters for BufferPool to return the information so that
[Buffer init] can figure out what is the most appropriate class
(which might be even better).
--
Glenn Andreas email@hidden
<http://www.gandreas.com/> oh my!
Mad, Bad, and Dangerous to Know
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden