2

In my app at a certain point I'm releasing on of the objects I created using:

[myObject release];

I have a feeling something is not really working over there (I have a bug which I cannot catch, and I have an assumption it has something to do with the memory allocation). I'm trying to look it overt in the Debugger and it seems that the object still have the same values after the "release" line was running.

Am I missing anything?

Is the memory still allocated and being dismissed someplace else? If so, where?

JasonMArcher
  • 12,386
  • 20
  • 54
  • 51
Ohad Regev
  • 5,521
  • 12
  • 58
  • 82
  • 1
    It might also be a good idea to set the pointer to NULL so that you don't try to access this memory again. – Luke Jun 13 '11 at 15:47
  • Please read [Memory Management Programming Guide](http://tinyurl.com/4lqj2yb). It explains what happens when you release an object, how objects are eventually deallocated, and lots of other things that you need to know. – Caleb Jun 14 '11 at 07:04

2 Answers2

2

When memory is being released, it’s usually not zeroed out. That means that objects appears to keep their status quo even after deallocated – but you can’t use them anymore, since the memory contents could be reused and overwritten by something else at any moment.

One common simple trick is adding a logging statement to dealloc:

- (void) dealloc
{
    NSLog(@"Say bye to %@, kids!", self);
    [super dealloc];
}

This is so simple that it can’t go wrong. Which is a good thing when you’re debugging and want to be 100 % sure about something.

Another nice tool is zombies. When you set a special environment variable, the machine will guard access to all objects and will scream when you try to access a deallocated one. It’s also quite a dependable tool.

And then there’s retainCount. It’s probably quite close to what you are looking for, but it’s not very dependable, as there are many things going on in the background. You should only use it if you know what you’re doing.

Community
  • 1
  • 1
zoul
  • 96,282
  • 41
  • 242
  • 342
  • 1
    I'd vote you up, but you mentioned `retainCount`... :-) I think it's more useful to point people to Instruments than even mentioning that (unholy) one. Other than that, good answer! – Johan Kool Jun 13 '11 at 16:05
  • 1
    Did someone say `retainCount`? Ahhhh, release the hounds! – sudo rm -rf Jun 13 '11 at 18:24
  • 1
    If you know what you are doing, you don't use `retainCount`. – bbum Jun 13 '11 at 20:48
  • I’ve noticed how many people think that even typing `retainCount` will release the missiles. I don’t think it’s that bad. Most of the time I can easily explain the numbers it returns and I find it helpful. – zoul Jun 14 '11 at 04:55
  • Sure, `retainCount` can be handy at times, but I don't think it's a good idea to point a newbie to it. – Johan Kool Jun 14 '11 at 11:03
  • 1
    retainCount is only useful until it isn't. Then you spend N[N] minutes trying to figure out why the value is what it is only to realize it is an implementation detail. Or the value changes in certain situations across software updates. Or you realize the value is artificially high because the object is autoreleased. ...etc... Ultimately, retainCount is grossly misleading to the newbie and experienced folk know that there is always a better way save for acts of debugging desperation. – bbum Jun 14 '11 at 16:34
-3

Instead of releasing it try,

myObject=NULL;

NSLog(@"Retain count of myObject is %d", [myObject retainCount]); // Since retainCount returns an integer, we use %d to display it 

You will see that its retaincount is 0.

You can also check myObject value

NSLog(@"myObject Value after NULL = %@", myObject); 

myObject Value after NULL = (null)

P.J
  • 6,725
  • 9
  • 41
  • 73
Vikr
  • 121
  • 1
  • 7
  • 1
    retainCount can never return zero. Your code is not doing what you think it is. – bbum Mar 15 '13 at 13:51
  • 1
    In the absence of ARC, this will leak the object; you need to send it a `release` or `autorelease` message to release it. In the presence of ARC, assigning `nil` (or `NULL`) to a variable is usually redundant. – Peter Hosey Mar 15 '13 at 19:33
  • when i tried getting the output for retaincount using the above code..it returned zero. @bbum – Vikr Mar 18 '13 at 13:09
  • @PeterHosey when i send a release message its retain count is suppose to decrease by 1 right? It so didn't happen and it worked after specifying myObject=NULL; (or) myObject=nil; Can you tell we where i went wrong? – Vikr Mar 18 '13 at 13:11
  • 1
    @Vikr Think about it; what does `myObject = NULL;` do? What are you *actually* sending the `retainCount` to? What happens if you do `[[NULL alloc] init];`? Or `NSLog(@"%@, %@", [NULL description], [myObject description]);`? – bbum Mar 18 '13 at 17:00
  • 1
    @Vikr: Your description of `release` is mostly right, but not relevant to your answer. Outside of ARC, assigning `NULL` to a variable is not the same as a release message: you aren't releasing the object, merely replacing its pointer in the variable with the `NULL` pointer. Then, as @bbum is hinting, you send a `retainCount` message to `NULL`, which is the same as a message to `nil`: it unconditionally returns zero. This proves nothing, since you sent the message to `NULL`, not to an object; a `retainCount` message *to an object* can never return zero. – Peter Hosey Mar 18 '13 at 18:25
  • 1
    An object that receives a `release` will decrement its retain count, *unless* its retain count is 1, in which case it will simply deallocate itself. There's no point in decrementing the retain count to zero, because once the object has deallocated, it is no longer valid for anything to send the dead object any message, including `retainCount`. – Peter Hosey Mar 18 '13 at 18:28
  • 1
    .... and calling any method on a deallocated object results in undefined behavior, thus `retainCount` can never [consistently] return 0. – bbum Mar 18 '13 at 18:52
  • @PeterHosey Thanks for the detailed answer. Now it makes sense. Just one clarification from the above question - so when retainCount is 1 it will simply deallocate itself. Thus question answered – Vikr Mar 19 '13 at 13:42
  • 1
    No, you can't assume the object will be deallocated when `release` is called and the `retainCount` is 1. An implementation detail may cause the object to be reset & marked for recycling, for example. Also note that the `retainCount` does not reflect `autorelease` state; there may be a `release` that'll happen later when a pool is drained. @Vikr I hope you didn't take my response as snark; it was meant as a learning exercise. – bbum Mar 19 '13 at 15:00