Got a quick question for ya, if I declare a String inside a function (local scope) do I have to manually release this String at the end of the function or is this automatically handled since the String is local in scope?
Unless you say 'manual', it's GC'd when it goes out of scope and the local environment releases the one ref to it, unless you of course hand it off to someone else outside the scope. ie, normal GC semantics.
If you say 'manual', then you take responsibility for it. If you screw up, well, then you screw up. *My* way of dealing with manual on exiting scope is to clean it up unless the dev manually handed it off to another code bit. ie, if you create a new object in a retrieval method, and hand it back as the return value, and you declared that object as manual, you're taking responsibility for the life of that object. In C++ semantics, if you declared it as a pointer, you've gotta be sure you delete it somewhere. In Java semantics, you'd be responsible for keeping track of it yourself and ending it elsewhere.
I know, it seems like a pain, but it comes in handy in *some* circumstances. Even mark/sweep GC systems will miss some dead-object situations, and in others (particularly dynamic load/unload of serialized code snippets) you want to ensure that object trees *aren't* deleted by the GC before you get a chance to work them back into the system.
*shrug* GC is a nice tool to have, but it's not a panacea yet.
I guess I wasn't clear? I mean in today's world, using today's tools, do I have to send a [StringObj release]; message at the end of my method even though it's local in scope?
Not unless you said [stringObj: retain] prior, or received that object from a pool-aware creation method that did so. (Crap, what's the key phrase used in Cocoa... grrr... can't recall offhand. The default init methods give you a raw unmanaged object, but others hand back a managed obj, the name tells you which are which.)
If no one set it up with a retain, then it follows traditional C/C++ semantics, and self-destructs on exiting local scope.
Here we go, from file:///Developer/Documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/MemoryManagementRules.html if you have the Dev Docs installed:
Quote:
This document summarizes the rules for memory management in Objective-C.
If you get an instance of an object via a method with ?alloc? or ?copy? in its name (or from the NSObject convenience method new), or if you send an instance a ?retain? message, you have a reference to it and will need to release it eventually.
If you get an instance of an object any other way (exceptions include multithreaded applications and some Distributed Objects situations), you must NOT release it and you must NOT hang onto it beyond the scope of the current method (if you need to hang onto it, retain it).
?autorelease? just means ?release this later? (for some definition of later.
I think I'm going to build some simple test apps and run them through gdb and see what happens.
BTW, I'm doing something like this at the beginning of the function:
NSString *someString = [[NSString alloc] init];
but I'm not doing a [someString release]; at the end of the function. From the snippet you quoted it sounds like I should do the release command at the end of my function.
then my program RAM useage didn't grow after the first time I clicked the button. The following code resulted in the same effect (RAM useage didn't grow):
then my program RAM useage went up by 96 bytes every time I clicked the button, proving I was leaking RAM.
I tested this using the Debug -> Launch with Tool -> Object Alloc, then clicking the 'show counts as bytes' option to see how my program was using RAM.
The real problem can crop up if the programmer explicitly deletes something manually which still has a refCount > 0. I would like to know exactly how the GC would handle that situation before I started mixing GC and manual memory ops (if that is a legal mix).
Anyone deleting objects out from under GC is going to have to deal with things themselves. The runtime can warn them that they're doing something stupid, as Kickaha suggested, but that's about it.
Under a GC system, you either explicitly or implicitly release an object, which (in Objective-C at least) decrements the ref count. The object is only cleaned up when the ref count hits zero (or some similar "nobody is using this" criterion is met). If you manually subvert that system, well, you get to manually deal with the consequences. Unlike with Java or Perl, there will always be ways to muck around in Objective-C, because of its roots in C. The best any GC system can be is self-consistent, and reasonably graceful about landing when someone pulls the rug out.
Comments
Got a quick question for ya, if I declare a String inside a function (local scope) do I have to manually release this String at the end of the function or is this automatically handled since the String is local in scope?
If you say 'manual', then you take responsibility for it. If you screw up, well, then you screw up. *My* way of dealing with manual on exiting scope is to clean it up unless the dev manually handed it off to another code bit. ie, if you create a new object in a retrieval method, and hand it back as the return value, and you declared that object as manual, you're taking responsibility for the life of that object. In C++ semantics, if you declared it as a pointer, you've gotta be sure you delete it somewhere. In Java semantics, you'd be responsible for keeping track of it yourself and ending it elsewhere.
I know, it seems like a pain, but it comes in handy in *some* circumstances. Even mark/sweep GC systems will miss some dead-object situations, and in others (particularly dynamic load/unload of serialized code snippets) you want to ensure that object trees *aren't* deleted by the GC before you get a chance to work them back into the system.
*shrug* GC is a nice tool to have, but it's not a panacea yet.
If no one set it up with a retain, then it follows traditional C/C++ semantics, and self-destructs on exiting local scope.
Here we go, from file:///Developer/Documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/MemoryManagementRules.html if you have the Dev Docs installed:
This document summarizes the rules for memory management in Objective-C.
If you get an instance of an object via a method with ?alloc? or ?copy? in its name (or from the NSObject convenience method new), or if you send an instance a ?retain? message, you have a reference to it and will need to release it eventually.
If you get an instance of an object any other way (exceptions include multithreaded applications and some Distributed Objects situations), you must NOT release it and you must NOT hang onto it beyond the scope of the current method (if you need to hang onto it, retain it).
?autorelease? just means ?release this later? (for some definition of later.
I think I'm going to build some simple test apps and run them through gdb and see what happens.
BTW, I'm doing something like this at the beginning of the function:
NSString *someString = [[NSString alloc] init];
but I'm not doing a [someString release]; at the end of the function. From the snippet you quoted it sounds like I should do the release command at the end of my function.
Originally posted by Hiro
Yep, without that you be leakin'.
Yea, I did a simple little program last night where I click a button and my outputString is dumped into a text field.
If I do this inside my action method:
NSString *outputString = [[[NSString alloc] initWithString:@"Test String"] autorelease];
then my program RAM useage didn't grow after the first time I clicked the button. The following code resulted in the same effect (RAM useage didn't grow):
NSString *outputString = [[NSString alloc] initWithString:@"Test String"];
// do some stuff
[outputString release];
// end of method
If I did this inside my action method however:
NSString *outputString = [[NSString alloc] initWithString:@"Test String"];
then my program RAM useage went up by 96 bytes every time I clicked the button, proving I was leaking RAM.
I tested this using the Debug -> Launch with Tool -> Object Alloc, then clicking the 'show counts as bytes' option to see how my program was using RAM.
Originally posted by Hiro
The real problem can crop up if the programmer explicitly deletes something manually which still has a refCount > 0. I would like to know exactly how the GC would handle that situation before I started mixing GC and manual memory ops (if that is a legal mix).
Anyone deleting objects out from under GC is going to have to deal with things themselves. The runtime can warn them that they're doing something stupid, as Kickaha suggested, but that's about it.
Under a GC system, you either explicitly or implicitly release an object, which (in Objective-C at least) decrements the ref count. The object is only cleaned up when the ref count hits zero (or some similar "nobody is using this" criterion is met). If you manually subvert that system, well, you get to manually deal with the consequences. Unlike with Java or Perl, there will always be ways to muck around in Objective-C, because of its roots in C. The best any GC system can be is self-consistent, and reasonably graceful about landing when someone pulls the rug out.