PDA

View Full Version : dealloc: not getting called




HiRez
Jun 11, 2008, 08:48 PM
I have a standard Cocoa project, just a Cocoa Application, not using CoreData and it's not document-based. For some reason, dealloc: is not getting called on my application controller object when the program quits normally (by selecting Quit from the File menu). My controller object is set as the application's delegate in the Nib, and I'm using Xcode 2.5 on Tiger, so I don't think it's a "garbage collection is turned on" thing. Everything else seems to be working (including awakeFromNib:) but I can't figure out why dealloc is not called. Here's the method:- (void)dealloc {
NSLog(@"***DEALLOCATING***");
if (pendingUploadFilePaths) [pendingUploadFilePaths release];
[context release];
[invoc release];
[super dealloc];
}Nothing shows up in the log and the log is working fine because I have NSLogs all over the place elsewhere in the same controller class.

EDIT: Is it because I instantiated this object in the Nib? Shouldn't all objects call dealloc: before they are destroyed? Do I need do all my cleanup in applicationWillTerminate: or something other than dealloc: in this case?



Darkroom
Jun 11, 2008, 09:18 PM
this is a super quick guess, and i'm not at all a seasoned developer, so feel free to ignore this, but shouldn't there be curly braces here:

- (void)dealloc {
NSLog(@"***DEALLOCATING***");
if (pendingUploadFilePaths) {[pendingUploadFilePaths release]};
[context release];
[invoc release];
[super dealloc];
}

could that be the problem?

HiRez
Jun 11, 2008, 09:36 PM
this is a super quick guess, and i'm not at all a seasoned developer, so feel free to ignore this, but shouldn't there be curly braces here:

- (void)dealloc {
NSLog(@"***DEALLOCATING***");
if (pendingUploadFilePaths) {[pendingUploadFilePaths release]};
[context release];
[invoc release];
[super dealloc];
}

could that be the problem?No, those are optional if the "if" statement is followed by a single line. I normally put even single lines inside braces as good practice (in case I later add lines inside the condition), but I felt lazy here. Anyway, I'm not getting any compiler warnings or errors and as I said, everything else in the same class is executing fine.

Darkroom
Jun 11, 2008, 09:39 PM
No, those are optional if the "if" statement is followed by a single line. I normally put even single lines inside braces as good practice (in case I later add lines inside the condition), but I felt lazy here. Anyway, I'm not getting any compiler warnings or errors and as I said, everything else in the same class is executing fine.

not so much going out on a limb here, but have you tried a clean build and restarted your computer? xcode can be bugville sometimes. or maybe it's just xCode3 that can get all crazy...

aLoC
Jun 11, 2008, 10:01 PM
There's no guarantee that an objects dealloc method will be called on app termination. From: http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.pdf

"Note that when an application terminates, objects may not be sent a dealloc message since the process’s memory is automatically cleared on exit—it is more efficient simply to allow the operating system to clean up resources than to invoke all the memory management methods. For more details about object creation and deallocation, see Object Creation."

It makes sense because the only thing that method is supposed to do is memory deallocation (i.e. no filehandle/db connection/other cleanup), so when quitting it's quicker to just skip all the method calling and deallocate the apps whole memory in one block.

Edit: also there's no need for the "if (pendingUploadFilePaths)" because sending a message to a nil object is not an error in Objective C like it is in Java (NullPointerException) or other languages. If the object is nil the message is just discarded.

kpua
Jun 12, 2008, 12:20 AM
If the controller was instantiated as a top-level object in a nib, you have to manually release it.

HiRez
Jun 12, 2008, 02:34 AM
There's no guarantee that an objects dealloc method will be called on app termination. From: http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.pdf

"Note that when an application terminates, objects may not be sent a dealloc message since the process’s memory is automatically cleared on exit—it is more efficient simply to allow the operating system to clean up resources than to invoke all the memory management methods. For more details about object creation and deallocation, see Object Creation."

It makes sense because the only thing that method is supposed to do is memory deallocation (i.e. no filehandle/db connection/other cleanup), so when quitting it's quicker to just skip all the method calling and deallocate the apps whole memory in one block.

Edit: also there's no need for the "if (pendingUploadFilePaths)" because sending a message to a nil object is not an error in Objective C like it is in Java (NullPointerException) or other languages. If the object is nil the message is just discarded.I guess that makes sense, it's odd though because I've written lots of Cocoa apps and have never recalled seeing this before, but maybe I just didn't notice. I guess I just have to be careful to move other cleanup operations out of my dealloc method if they need to get called.

Also, I knew about sending messages to nil being ok, I have no idea why I wrote it like that in this case...lack of sleep I guess.

@ kpua, how can I manually release my application controller object? It's all contained in the nib and is owned by nothing (since it is the top-level object of my application except for, I guess, NSApplication).

Anyway, thanks to all of you.

kainjow
Jun 12, 2008, 11:07 AM
The OS will release it for you when your process is ended. If you need to do cleanup when the app quits, use the applicationWillTerminate: notification.