It worked. You have given up ownership of this object, and when the system determines that it no longer belongs, it will be marked for reuse by the system. This can happen immediately if you were the sole owner of the string. This can happen at some later point if the creation of the string caused its auto-implementation inside. Or, as Dave DeLong points out, the system can optimize it into an object that is never released.
In your case, it is optimized into a constant string that will exist for the life of the program. If you were to use NSMutableString instead of NSString , you would notice funny behavior that probably won't crash but won't print what you expected. (See this question for an example.)
If you used NSArray instead, it would be freed when you call release , but you will still see that your NSLog example works correctly until you select any other object. Deallocation simply marks the memory as reusable; in fact, this is not clear. Therefore, if you passed an array to NSLog, that memory was not changed and therefore it still prints correctly.
The key to all of this, however, is recognizing that calling release does not necessarily cause the object to be freed. It can continue to exist for a number of reasons. But as soon as you call release , you have lost ownership of the object. If you continue to use it after this point, the system can do all kinds of strange things of its own free will, as shown.
source share