I am having trouble understanding why NSLog reports "dog" when the code is run. I understand about retain counts and dealloc e.t.c. What simple thing am i missing ?
NSString *newFoo = @"dog";
[newFoo release];
NSLog(newFoo);
I am having trouble understanding why NSLog reports "dog" when the code is run. I understand about retain counts and dealloc e.t.c. What simple thing am i missing ?
NSString *newFoo = @"dog";
[newFoo release];
NSLog(newFoo);
You are de-allocating the chunk of memory the pointer's pointing at, but the data is still there.
Releasing it doesn't automatically zeroes out that part of the memory.
So you can still read the data out just fine but it's just might be snapped (allocated) by something else down the line... but just not yet.
I'm not an ObjC coder by trade but as since its compatible with C that's I'm guessing from my C experience.
I believe it's because @"dog" is effectively treated as a constant by the compiler. It creates some subclass of NSString (which is a class cluster) which persists for the lifetime of the application.
Just discovered this question for the definitive answer, which is essentially the same as mine.
Even though newFoo has been released, meaning that its memory has been marked as re-allocatable by the runtime, the memory itself is not overwritten. Because newFoo still points to the location in memory where your string existed, the memory is still there and is still used.
The only reason you're not getting a segfault is that you just happen to not have allocated new memory over the location where newFoo pointed.
Bottom line: you're getting lucky. Never reuse a pointer that you've released.
[@"String Literal" release];
is a noop;
NSString *literal = @"String Literal";
[literal release];
is also a noop. This is only the case for string literals; and you should never expect this behaviour anywhere else. (This is to say; even though you tell the object to release, it just doesn't.)
Although the object is probably released (not sure how Obj-C handles strings internally, some languages basically cache strings), you have not writted anything new in the memory of newFoo
after you released it. The memory where the string was stored keeps its content, but could be overwritten at any time.
newFoo
still points to the same adress in memory, but that memory could become anything else at any moment.
The way to really be sure that you don't point to potentially dirt memory is to set newFoo
to nil
after you released it.
A String Literal is a special case.. http://thaesofereode.info/clocFAQ/
But in general assuming you are not using garbage collection just stick to the few simple rules..
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html
more pertinently.. retain an object when you need it to stick around - balance it with a release when done. If you didn't create or retain it, you don't need to release it.
Sending -release to an object isn't like freeing the memory, it only signals that you are done with it. It may well still be around or it may not. You have no way of knowing, you don't need to know, and you shouldn't try to find out if it is used elsewhere, if clever apple code has decided to cache it, if it's a singleton, etc.
It may well still be valid but when you have sent release you have effectively said "I'm done" and not "reclaim this memory".