Search code examples
objective-creleasenew-operatorinitalloc

-dealloc method not called when owning array dealloc'd... should it?


Here are two pieces of Objective-C code in a Foundation app. This piece of code is in a function:

    [arrayOfObjects addObject:[[TheShape alloc] init]];
    NSLog(@"%@", arrayOfObjects); // log verifies "<TheShape..." is in the array
    [arrayOfObjects release];

and in my TheShape class, I have this dealloc override method:

    - (void)dealloc {
        NSLog(@"TheShape dealloc called.");
        [super dealloc];
    }

Although my program works otherwise, it doesn't work the way I expect it to. When the [arrayOfObjects release] message is sent, I expect to see the "TheShape dealloc..." string appear in the log. It doesn't.

Q1: Why not?

So I dig a bit and simplify things. If I do something simpler like this:

    TheShape *aShape = [[TheShape alloc] init];
    [aShape release];

the debug message still doesn't appear in the log.

Q2: Why not?

But if I do this:

    TheShape *aShape = [TheShape new];
    [aShape release];

the debug message does appear in the log. The debug message also appears in the log if I change the alloc/init in the first sample to new, too.

Q3: Why?

Obviously, I'm missing something conceptual in the alloc/init/release cycle (Q's 1 and 2) and in the supposed equivalency of new and alloc/init (Q3). Can anybody point me to a tutorial that explains things a bit more for the hard of thinking, like me?

Thanks,

Bill


Solution

  • By any chance did you override +new on your class? It should be doing precisely the same thing as +alloc/-init.

    In any case, your very first line

    [arrayOfObjects addObject:[[TheShape alloc] init]];
    

    is leaking your TheShape instance. You should turn that in to

    [arrayOfObjects addObject:[[[TheShape alloc] init] autorelease]];