Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

GFLPraxis

macrumors 604
Original poster
Mar 17, 2004
7,152
460
Hello,
So, I originally started with a book, but have transitioned over to taking the Stanford CS 193p class on iTunes U, which has been a much better form of learning for me. I'm fairly early on in the class, but I had a question, and was wondering if I can get some assistance.


Take this theoretical piece of code:

Code:
NSMutableArray *poly = [NSMutableArray alloc] init];
PolygonShape *polygon1 = [[PolygonShape alloc] init];
PolygonShape *polygon2 = [[PolygonShape alloc] init];
PolygonShape *polygon3 = [[PolygonShape alloc] init];

[poly addObject:polygon1];
[poly addObject:polygon2];
[poly addObject:polygon3];

Followed by:
Code:
[polygon1 release];
NSLog(@"test1");

[polygon2 release];
NSLog(@"test2");

[polygon3 release];
NSLog(@"test3");

[poly release];
NSLog(@"test4");


With the note that PolygonShape has the following method, simplified:

Code:
- (void)dealloc
{
NSLog(@"dealloc ran");

//release some integer ivars

[super dealloc];

}


My Console results are:

Code:
test
test2
test3
dealloc ran

followed by an EXC_BAD_ACCESS crash.

Why is dealloc only running when the array is released and not the objects I'm running it on? Isn't it my responsibility to individually release everything I ran alloc/init on in the local scope?

Thanks for any clarification on how I'm looking at this. :)
 
Collection classes like NSArray, NSDictionary, and so on almost always retain the objects when you put them in.

After adding an object to an array, the array "owns" the object as well.
 
The code you posted appears to be correct, so I suspect the code you're running has some subtle differences from what you posted.

(Also the code you posted won't compile, it's missing a square bracket ;) )

<edit>
This response was only about the crash. The reason why -dealloc isn't running until then is as jared_kipe describes.
</edit>
 
Code:
- (void)dealloc
{
NSLog(@"dealloc ran");

//release some integer ivars

[super dealloc];

}

I believe this may be your problem here. Integers are not objects, you don't release them. Are you sure you're not getting any compiler warnings? GCC should have been pretty pissed if you were trying to tell it to send a message to a non-object.
 
Aha! It was the combination of the two.

I did get some compiler warnings, and Guiyon's post explains the crashing, but I was focusing on the memory management question before tackling the crash.

I was trying to figure out why Dealloc wasn't being called until later; and jared_kipe hit the nail on the head. I didn't realize the array retained it. That explains why Dealloc was being called only after the array was released.

Thanks much, all.
So, I take it that this means that calling release on an array also makes it release everything it holds, correct?


OK, so one last thing. The application completes fully, but the console logs the following error:

Code:
2010-06-24 22:18:04.499 WhatATool[2547:80f] *** __NSAutoreleaseNoPool(): Object 0x1050f0 of class NSCFString autoreleased with no pool in place - just leaking
2010-06-24 22:18:04.507 WhatATool[2547:80f] *** -[NSAutoreleasePool drain]: This pool has already been released, do not drain it (double release).

Anu thoughts on the meaning of his?
 
So, I take it that this means that calling release on an array also makes it release everything it holds, correct?
That's only true if the array is dealloc'ed as a result of your release. Just because you relinquish ownership of some object doesn't mean every other owner loses its ownership.

Now, if you know that you are the sole owner of an object, and you release it, then in general, it's going to dealloc itself. For any object that has an owning reference to any other object, it will then release its owned objects. This is in accordance with the rules in the Memory Management Guide for writing dealloc's. Do you have any reason to think that NSArray wouldn't follow the same rules as every other class?


OK, so one last thing. The application completes fully, but the console logs the following error:

Code:
2010-06-24 22:18:04.499 WhatATool[2547:80f] *** __NSAutoreleaseNoPool(): Object 0x1050f0 of class NSCFString autoreleased with no pool in place - just leaking
2010-06-24 22:18:04.507 WhatATool[2547:80f] *** -[NSAutoreleasePool drain]: This pool has already been released, do not drain it (double release).

Anu thoughts on the meaning of his?
The first message means exactly what it says. An object of the stated class was autoreleased with no pool in place. Coincidentally, the second message also means exactly what it says. It shows you the message, -[NSAutoreleasePool drain], and tells you why it's wrong.

If you're looking for an explanation of why you're getting these messages, then you'll have to post your code.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.