PDA

View Full Version : after init, dealloc, but not called?




mdeh
Mar 15, 2009, 09:27 AM
P 89 Hillegas.

May I ask a question about dealloc.
In this exercise, a very simple program synthesizes speech, using an instance of NSSpeechSnythesizer.

The ivar is instantiated in the init call, thus;

-(id) init
{
NSLog(@"Initializing speech syntersizer");
self = [super init];

if ( self)
{
speechSynth = [[NSSpeechSynthesizer alloc] initWithVoice: nil];
}

return self;
}

So, having meticulously :D studied the "rules" I wrote a dealloc method like so. ( The documentation does not mention that initWithVoice is autoreleased, but rule one, AFAIR, says an **alloc** needs to be released. ( Not running GC)

-(void) dealloc
{
NSLog(@"Deallocking speech syntersizer");
[speechSynth release];
[super dealloc];

Now to be fair, Hillegas does **not** use a dealloc, so I wonder if someone can clear up this confusion, ie why dealloc is not called. ( I am assuming it is not called as NSLog is not written).
Thanks



eddietr
Mar 15, 2009, 09:44 AM
In the documentation for NSObject:


Important: 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 this and other reasons, you should not manage scarce resources in dealloc—see Object Ownership and Disposal in Memory Management Programming Guide for Cocoa for more details.

mdeh
Mar 15, 2009, 02:23 PM
In the documentation for NSObject:


Hi Eddie...I tried to find this reference, but what I came up was, was this..which is interesting.


Re: Question about the dealloc method
Posted: Sep 23, 2008 7:01 AM in response to: xxxxxxxx
Reply Email

Could you provide an exact reference to where it says that in the documentation. Because, if you do, I will file a bug report on it. That is bad, bad, bad advice. The operating system will not automatically release "resources" when your application exits. It will reclaim some of them, such as (some) memory and files (I think), but not all. I don't have the full list of all possible resources and how they are handled by the OS when an applications exits without explicitly releasing them. Even if I did, I would never rely on it. How much extra time does it take at program exit to release resources?

To answer your question - ignore bad advice.


Well...it seems to me that the note does **not** say not to implement a dealloc method, it says more that it **may** not be called.....
So, thanks for pointing that out...just trying to understand what I should make of this.

eddietr
Mar 15, 2009, 03:54 PM
I'm on my phone, so I can't copy/paste a reference. :)

But just go to Xcode->Help->Documentation-> and search for NSObject.

Then go down to dealloc.

As for the comment you found, the point is that the framework is not going to sit there and dealloc every object in your app when the whole process is going away anyway.

So if you have something you absolutely need to clean up in an object which lives until the end of the application lifecycle, then make sure you take care of it in applicationWillTerminate.

lee1210
Mar 15, 2009, 04:01 PM
The email quoted sounds a bit suspect. The resources you (or at least I) would be really concerned with would be something that the system can't control, such as network resources, etc. To a certain extent i'd be concerned about posix mutexes, etc. but I wouldn't really think that someone is doing the "right" thing if a mutex is held for the lifecycle of an object (unless the lifecycle is very short, and tightly controlled). I'm sure someone can come up with a reason, but it seems suspect to me.

-Lee

mdeh
Mar 15, 2009, 04:24 PM
I'm on my phone, so I can't copy/paste a reference. :)

But just go to Xcode->Help->Documentation-> and search for NSObject.

Then go down to dealloc.

As for the comment you found, the point is that the framework is not going to sit there and dealloc every object in your app when the whole process is going away anyway.

So if you have something you absolutely need to clean up in an object which lives until the end of the application lifecycle, then make sure you take care of it in applicationWillTerminate.

Eddie..I am at work too...so will look at this later..but I think I am seeing the context in which this was written. More later :-)

mdeh
Mar 15, 2009, 04:25 PM
The email quoted sounds a bit suspect. The resources you (or at least I) would be really concerned with would be something that the system can't control, such as network resources, etc. To a certain extent i'd be concerned about posix mutexes, etc. but I wouldn't really think that someone is doing the "right" thing if a mutex is held for the lifecycle of an object (unless the lifecycle is very short, and tightly controlled). I'm sure someone can come up with a reason, but it seems suspect to me.

-Lee


Thanks Lee...will look more closely later

mdeh
Mar 16, 2009, 02:59 AM
I'm on my phone, so I can't copy/paste a reference. :)

But just go to Xcode->Help->Documentation-> and search for NSObject.

Then go down to dealloc.

As for the comment you found, the point is that the framework is not going to sit there and dealloc every object in your app when the whole process is going away anyway.

So if you have something you absolutely need to clean up in an object which lives until the end of the application lifecycle, then make sure you take care of it in applicationWillTerminate.


I found this here http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/mmNibObjects.html

The issue of responsibility for nib object disposal becomes clearer when you consider the various kinds of applications. Most Cocoa applications are of two kinds: single window applications and document-based applications. In both cases, memory management of nib objects is automatically handled for you to some degree. With single-window applications, objects in the main nib file persist through the runtime life of the application and are released when the application terminates; however, dealloc is not guaranteed to be automatically invoked on objects from the main nib file when an application terminates.


Now, I know this has been discussed, but just to be sure, I ??assume from the above, that speechSynth will be automatically released "when the app terminates". But, am I not violating rule 1 of memory management, which says if I alloc an object, I am responsible for releasing it?

eddietr
Mar 16, 2009, 08:09 AM
Now, I know this has been discussed, but just to be sure, I ??assume from the above, that speechSynth will be automatically released "when the app terminates". But, am I not violating rule 1 of memory management, which says if I alloc an object, I am responsible for releasing it?

Oh, I'm not suggesting that you not have a proper dealloc method where you release everything you alloc'ed. You should do this as a matter of writing good, complete, well organized code.

But, the point is don't count on it being called. If you have things like open file handles, or pipes, or connections to another process/server that you want to make sure are cleanly closed when the user quits, then you need to make sure you do those in applicationWillTerminate.

If you wait until dealloc to do that type of clean up, dealloc may never come.

Or another way to look at it, is that you never call dealloc directly and you don't have control of when or if dealloc is called. Your job is to provide a complete dealloc method that frees memory you have allocated. The framework's job is to use that dealloc when appropriate.

More on this can be found here: Resource Management (http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-SW6)

mdeh
Mar 16, 2009, 08:12 AM
Oh, I'm not suggesting that you not have a proper dealloc method where you release everything you alloc'ed. You should do this as a matter of writing good, complete, well organized code.

But, the point is don't count on it being called. If you have things like open file handles, or pipes, or connections to another process/server that you want to make sure are cleanly closed when the user quits, then you need to make sure you do those in applicationWillTerminate.

If you wait until dealloc to do that type of clean up, dealloc may never come.

Or another way to look at it, is that you never call dealloc directly and you don't have control of when or if dealloc is called. Your job is to provide a complete dealloc method that frees memory you have allocated. The framework's job is to use that dealloc when appropriate.


Ok...now I am happy!!!! :D

eddietr
Mar 16, 2009, 08:17 AM
Ok...now I am happy!!!! :D

Good. :)

BTW, I like the way you are learning and understanding every issue (and most importantly, every term) rather than just slapping together some code you copied (or guessed at) and calling yourself a Cocoa programmer. This is the kind of approach that marks a really good developer.

Excuse the presumption, but down the road if you're ever in the market for a development job, PM me.

dmhjah
Apr 4, 2009, 01:03 PM
I'm on my phone, so I can't copy/paste a reference. :)

But just go to Xcode->Help->Documentation-> and search for NSObject.

Then go down to dealloc.

As for the comment you found, the point is that the framework is not going to sit there and dealloc every object in your app when the whole process is going away anyway.

So if you have something you absolutely need to clean up in an object which lives until the end of the application lifecycle, then make sure you take care of it in applicationWillTerminate.

I am new to Objective-C and Cocoa. I am reading Xcode->Help->Documentation-> and search for NSObject. Correct me if I am wrong, but it sounds like if I didn't allocate and init the object then I should let the system take care of the memory management for that object. If I create it then I should take care of the objects memory managemet. Does this sound like a fair statement?

lee1210
Apr 4, 2009, 02:22 PM
I am new to Objective-C and Cocoa. I am reading Xcode->Help->Documentation-> and search for NSObject. Correct me if I am wrong, but it sounds like if I didn't allocate and init the object then I should let the system take care of the memory management for that object. If I create it then I should take care of the objects memory managemet. Does this sound like a fair statement?

Read this:
http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

if you are using garbage collection in Objective-C 2.0, you never worry about it. If you are not, there are rules for autorelease pools that you should figure out. If an object is passed the autorelease message, the next time an autorelease pool is drained it will have it's retain count decreased by 1. If this brings its retain count to 0, it will be released/dealloc'd. The general rule is that if a method contains alloc, new or copy, you need to retain it. Otherwise the object should returned to you should be autoreleased, so you only need to retain it if you intend to take ownership of the object.

-Lee

eddietr
Apr 4, 2009, 06:16 PM
Correct me if I am wrong, but it sounds like if I didn't allocate and init the object then I should let the system take care of the memory management for that object. If I create it then I should take care of the objects memory managemet. Does this sound like a fair statement?

Well, if you alloc an object, then you are responsible for releasing that object at some point. Because you have caused that object to have a release count of 1 by allocating it. So that much is true.

But that's not the only time you would be responsible for releasing the object. Another case would be if you retained the object. So for example suppose you had a property like this:


@property (nonatomic, retain) NSString* someString;


And then somewhere else you do this:


self.someString = [NSString stringWithFormat:@"something like this %d", someInt];


So in this case you have not alloc'ed the NSString, but you still have to release it at some point. Because although the string you get back from stringWithFormat is autoreleased, you have also retained that object by using the someString property setter.

So you have to be aware (and manage) not just objects you allocated, but also any objects you have retained.