views:

50

answers:

2

Hello,

I have the following simple piece of code:

NSMutableArray *array = [[NSMutableArray alloc] init];

    NSObject *o = [[NSObject alloc] init];
    NSObject *o1 = [[NSObject alloc] init];
    NSObject *o2 = [[NSObject alloc] init];

    [array addObject:o];
    [array addObject:o1];
    [array addObject:o2];
    NSLog(@"-------");
    NSLog(@"%d, %d, %d, %d\n", [o retainCount], [o1 retainCount], [o2
                                                                   retainCount], [array retainCount]);
    [array release];
    NSLog(@"%d, %d, %d, %d\n", [o retainCount], [o1 retainCount], [o2
                                                                   retainCount], [array retainCount]);
    [o release];
    [o1 release];
    [o2 release];
    NSLog(@"-------");
    NSLog(@"%d, %d, %d, %d\n", [o retainCount], [o1 retainCount], [o2
                                                                   retainCount], [array retainCount]);

as an output I'm getting:

[Session started at 2010-10-27 18:00:59 +0200.]
2010-10-27 18:01:02.186 Questions[22463:207] -------
2010-10-27 18:01:02.187 Questions[22463:207] 2, 2, 2, 1
2010-10-27 18:01:02.188 Questions[22463:207] 1, 1, 1, 1
2010-10-27 18:01:02.188 Questions[22463:207] -------

and the program crushes with EXC_BAD_ACCESS.

my question is following: I understand that after calling [array release] the array object does not exist anymore, right? and the same is for calling release for the other objects, yes? If so, why I don't get EXC_BAD_ACCESS after calling [array retainCount]? why it returns any value? and why calling retainCount on the other objects causes EXC_BAD_ACCESS?

Thanks for your help!

+1  A: 

Because you released array and then are trying to access it again.

[array release]; // array is no longer in memory, therefore you can no longer use it.
[array retainCount]; // crash!

Even though you call release on an object, sometimes that object can stays in memory for a little longer. I recommend that you set any variable that you may reuse to nil after releasing it.

[array release];
array = nil;
[array retainCount]; // no more crash 
jojaba
+3  A: 

Well, as you correctly guessed you can't send messages to objects that have already been released. The behavior if you do so is unspecified, so EXC_BAD_ACCESS might be raised, but it need not be.

If you want to get retainCount from objets you already released, you should check out NSZombieEnabled(http://www.cocoadev.com/index.pl?NSZombieEnabled), which will cause objects to be released but not dealloc'ed.

Johannes Rudolph