Re: Memory Management
Re: Memory Management
- Subject: Re: Memory Management
- From: Nat! <email@hidden>
- Date: Wed, 8 Aug 2001 09:54:59 +0200
Am Montag, 6. August 2001 um 10:06 schrieb Ondra Cada:
>
Nat!,
>
>
>>>>>> Nat! (N) wrote at Mon, 6 Aug 2001 02:51:41 +0200:
>
N> There's some poor advice given on this issue, which is probably just
>
N> confusing to a beginner.
>
>
There is, but alas, it happened in _your_ text...
>
>
N> The original code from Mike Vannorsdel is fine (IMO), with the
>
exception
>
N> that the assignments to self are superflous and misleading.
>
>
...since that's quite the opposite case!
>
>
N> Superflous, because neither NSView nor NSObject will return anything
>
N> else but self.
>
>
How do you know that? Of course, I know too that the _current_
>
implementation of NSObject and NSView _happens_ not to do that, but
>
writing
>
your code this way you seriously compromise the flexibility.
If you'd read the documentation you'd realize that both methods are
documented to return self. Since that is documented behaviour it doesn't
compromise nothing.
>
>
It is always possible that
>
- the future implementation would do that;
No, not without breaking the documented API. If the API changes you have
to recode, that's normal.
>
- for some reason a category or posedAsClass will be used which would
>
do that.
Buggy categories or buggy posedAsClass.
>
>
Beside that, improving the code in future, you can any time decide to
>
move
>
the class to some other place in the inheritance tree. With properly
>
written
>
code, it means just changing the superclass name in @interface, and
>
that's
>
that. With the kind of code you advocate it means checking carefully
>
all the
>
long ago written (and long ago forgotten) parts whether they might or
>
might
>
not bring some problems...
Checking carefully if moving some class through the inheritance chain of
"long ago written parts" breaks something is sooo obviously wrong, that
I feel ashamed even thinking of it. :)
>
>
N> Misleading, because they give the impression that super init...
>
could
>
N> return something else but self.
>
>
Primarily, it _CAN_ return nil (see below). Besides, what's "self"? Of
>
course init _always_ returns self (or nil), but *THE SELF OBJECT CAN BE
>
DIFFERENT FROM THE ONE WHICH WAS init's ORIGINAL RECEIVER*!!! See again
>
my
>
code
I was still talking about Mikes code there. I was noting that in
- (id) init
{
self = [super init];
ivar1 = someValue;
return( self);
}
the self assignment was superflous and misleading, as I explained.
OK now to your code. You claimed that your "generic pattern" would fix
problems when subclassing a class with both of the two lower init methods
>
Actually, it is better to get used to the generic pattern of
>
>
-init... {
>
if ((self=[super init...])!=nil) {
>
...
>
}
>
return self;
>
}
>
>
Someone higher on the inheritance tree might have used something like
>
>
-init... {
>
...
>
if (there-is-no-sense-in-making-this-object) {
>
[self autorelease];
>
return nil;
>
}
>
...
>
}
>
>
or even
>
>
-init... {
>
...
>
if (so-long-Dr-Jekyll) {
>
[self autorelease];
>
return [[Hyde alloc] init...];
>
}
>
...
>
}
>
>
If it happens to be so, your init would not work properly.
>
>
>
N> It would crash also, if there was a different object
>
N> returned, because it would certainly not be of our subclass
>
>
This certainty looks to me *QUITE* uncertain.
It does help in the first case, but check out this code, where I
followed you in the second case...
#import <Foundation/Foundation.h>
//
// The class we want to subclass
//
@interface Jekyll : NSObject
{
int amIEvil;
}
- (id) initWithValue:(int) value;
@end
//
// The "hidden" or not so hidden subclass we are
// substituting in init
//
@interface Hyde : Jekyll
{
}
@end
@implementation Jekyll
//
// Basically a plain copy of
// -init... {
// ...
// if (so-long-Dr-Jekyll) {
// [self autorelease];
// return [[Hyde alloc] init...];
// }
// ...
//}
//
- (id) initWithValue:(int) value
{
if( (self = [super init]) == nil)
return( self);
if( value == 666)
{
[self release];
return( [[Hyde alloc] init]);
}
amIEvil = value;
return( self);
}
- (NSString *) description
{
return( [NSString stringWithFormat:@"%@ = %d", [super description],
amIEvil]);
}
@end
//
// This is just a stupid substitution subclass
// in real life that could be a shared instance
// f.e.
//
@implementation Hyde
- (id) init
{
if( (self = [super init]) == nil)
return( self);
amIEvil = 666;
return( self);
}
@end
//
// OK. Here comes the subclass of Jekyll, the point
// of this whole discussion.
//
@interface SonOfJekyll : Jekyll
{
char comment[ 1024]; // so our subclass does need some more
ivar space...
}
@end
@implementation SonOfJekyll
- (id) initWithComment:(char *) s
{
// blessed are the meek for they shall inherit ...
if( (self = [super initWithValue:rand() % 10 + 660]) == nil)
return( self);
strncpy( comment, s, sizeof( comment));
return( self);
}
@end
int main (int argc, const char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
unsigned int i;
id p;
for( i = 0; i < 100; i++)
{
p = [[SonOfJekyll alloc]
initWithComment:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"];
NSLog( @"%d : %@", i, p);
[p release];
}
// insert your code here
[pool release];
exit(0); // insure the process exit status is 0
return 0; // ...and make main fit the ANSI spec.
}
//
// (gdb) Starting program: /Network/Users/nat/src/test/test
// [Switching to process 759 thread 0x2600]
// Aug 08 02:05:00 test[759] 0 : <SonOfJekyll: 0x4ebf8> = 660
// Aug 08 02:05:00 test[759] 1 : <SonOfJekyll: 0x4ebf8> = 665
// Aug 08 02:05:00 test[759] 2 : <SonOfJekyll: 0x51050> = 664
// Aug 08 02:05:00 test[759] 3 : <SonOfJekyll: 0x51050> = 661
// Aug 08 02:05:00 test[759] 4 : <SonOfJekyll: 0x51050> = 664
// Aug 08 02:05:00 test[759] 5 : <SonOfJekyll: 0x51050> = 669
// Aug 08 02:05:00 test[759] 6 : <SonOfJekyll: 0x51050> = 662
// Aug 08 02:05:00 test[759] 7 : <SonOfJekyll: 0x51050> = 665
//
// Program received signal SIGSEGV, Segmentation fault.
//
>
>
N> There is no "generic pattern" that will always work, when the init
>
N> routine is specified to return a "different" object. It depends on
>
what
>
N> that object is. Probably subclassing such a class is a bad idea.
>
N> If you're really keen on some "pattern" better use this:....
>
>
Ouch. Try start to with studying ObjC documentation -- like the
>
following
>
NSObject.html excerpt:
>
>
and using the language and API it for a few years, _THEN_ trying to
>
suggest
>
new conventions.
>
If you would have made the effort to not just read but understand what I
wrote, you would have noticed that I tried to argue against a
convention...
Nat!