views:

541

answers:

3

Hi. The simplest code ever in Objective-C causes weird behavior:

#import Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSObject *obj = [[NSObject alloc] init];
    NSLog(@"retain count %d",[obj retainCount]);//print 1
    [obj release];//obj deallocated
    NSLog(@"retain count %d",[obj retainCount]); //still printing 1 in Snow Leopard! Why??


    [pool drain];
    return 0;
}

The 2nd NSLog should print "message retainCount sent to freed object=0x103eb0". If you use Leopard everything works fine, but in Snow Leopard the 2nd NSLog still prints 1. Is there any bug i XCode delivered for Snow Leopard?? Thanks

+6  A: 

See this question.

It's not a bug. Once you release an object with a retain count of one, the objc runtime simply calls dealloc and does not bother decreasing the retain count. That's how it's always worked. Also, just because an object has been sent dealloc doesn't mean its data on the heap is immediately destroyed. It's just marked for destruction later.

Marc W
The memory is not so much "marked for destruction" as "available for reuse by something else". But nothing explicitly overwrites the freed memory right when its freed.
Ken
+1  A: 

Sending a message to a deallocated instance is undefined behavior. You are not supposed to do it. It could work; it could not. Because you are not supposed to do it, they do not have to make it so that the result is consistent with your expectations.

newacct
+1  A: 

Setting NSZombieEnabled to YES in the environment variables of your application will allow Foundation to detect this programming error, and report it as a console message which is helpful for debugging.

Jed Smith