2

I am checking on the retain count of some objects

NSLog(@"r = %d", [aObject retainCount];

It seems that the lowest value I can get is "r = 1", even if I deliberately add extra "release" calls

[aObject release];

The "r = 1" limit holds even if I try to put the "release" and "NSLog" test codes in the object's dealloc method.

The Cocoa run-time just seems to neglect my extra releases up to "r = 1" before crashing with an "EXC_BAD_ACCESS" at the very end of the sample program (without GC).

My only explanation (a guess) is that we need r >= 1 for the object to be accessed. And the Cocoa run-time just tries to refrain from letting any object's retain count from getting to 0 prematurely.

Can somebody confirm or correct me if I am wrong?

jscs
  • 63,694
  • 13
  • 151
  • 195
Stanley
  • 4,446
  • 7
  • 30
  • 48

6 Answers6

6

When the retain count of an object is about to reach 0 (i.e. its retain count is 1, and release has been called again), it's deallocated instead of bothering to do the final decrement.

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • That explains the "r = 1" limit. But it would be good for checking errors if "r" can be decremented to 0 or even negative values before stopping. They could implement this in Debug mode and it could be a useful additional feature ... – Stanley Feb 07 '11 at 23:09
  • That's an interesting theory, but it doesn't explain how you sometimes get `retainCount` to be `-1` :) – Nikita Rybak Feb 07 '11 at 23:29
  • 1
    @Stanley: The feature you are looking for is called Zombies, and it is included. Simply decrementing the retain count to 0 would be pointless, since there would still be no valid code to ask an object for that retain count. – Chuck Feb 07 '11 at 23:47
  • Thanks Chuck, the retainCount call does not seem to be popular at all when I check around with the kind advices coming in. It's good know that some methods that should be used and some shouldn't early on ... – Stanley Feb 08 '11 at 00:05
  • 2
    Nikita: try interpreting it as unsigned instead of signed. That's a "magic" retain count for objects that don't participate in reference counting. Basically though, don't use -retainCount. – Catfish_Man Feb 08 '11 at 00:22
6

As I've learned from bbum (and others), don't use retainCount. It isn't intended to be informative as to the retain state of an object. Just read the Memory Management Programming Guide and do not deviate from its practices. Don't try to use retainCount for your memory management.

See How many times do I release an allocated or retained object?,

When to use -retainCount?,

etc.

Community
  • 1
  • 1
Thomson Comer
  • 3,919
  • 3
  • 30
  • 32
3

If retainCount ever == 0, the singularity has been achieved!

Chicken meet egg. Or is it egg meet chicken.

By definition, releasing an object with a single remaining retain means the object is deallocated. Any subsequent method calls will result in undefined behavior.

bbum
  • 162,346
  • 23
  • 271
  • 359
1

The Instruments tool provides Zombie detection, which is more effective than trying to debug Cocoa's reference counting yourself. Use Xcode's Run > Run with Performance Tool > Zombies command. It detects when you are calling a method on a released object and shows the retain/release history for the complete lifecycle of the object. Life is much better since Apple added this tool.

jon
  • 31
  • 2
0

When an object's reference becomes 0 ,this object becomes "zombie object", but you can still send retainCount message to it that's because Xcode by default didn't "Enable Zombie Objects" in Memory Management, which means Xcode didn't check zombie objects.

If you make Xcode check zombie objects by tick on "Enable Zombie Objects" in "Edit Scheme->Run->Diagnostics->Enable Zombie Objects", you will receive error message when you continue send message to object after it's reference become 0.

The snapshot:

enter image description here

0

The philosophy of a memory management based on reference counting is that an object exists while it referenced >=1 times. retainCount = 0 theoretically means that the object not referenced anymore, that's why you can't obtain [aObject retainCount] == 0; because if you still can pass messages, the object exists and remains referenced by aObject, thus has at least retainCount = 1.

Martin Babacaev
  • 6,240
  • 2
  • 19
  • 34
  • You can hold a hundred of references to 'deceased' object, and it won't stop its memory from being reused and your application from crashing. – Nikita Rybak Feb 07 '11 at 23:28
  • @Nikita: if there is a number of references to an object, and this object is `deceased`, it's means that somewhere has been violated one of the _memory management_ rule. If you want to see this concept working, just try to respect [these](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH) rules. – Martin Babacaev Feb 07 '11 at 23:47
  • @Martin How are memory management guidelines relevant to the question? You just said that `aObject` variable referencing that instance affects `retainCount` and I'm saying it's irrelevant. – Nikita Rybak Feb 07 '11 at 23:50
  • @Nikita Rybak: He did not say variables affect the retain count. That was your extrapolation. – Chuck Feb 08 '11 at 00:00
  • @Nikita: It's just about mem management conception conformance at framework level (in this case starting from `NSObject` class). That could explain why `NSObject` implementation doesn't decrement `reteinCount` of inherited object infinitely, but just register it for inevitable (sometimes postponed) `dealloc`. – Martin Babacaev Feb 08 '11 at 00:03
  • 1
    It is rather more simple than that; there is no reason for the system to waste a cycle or two decrementing the retain count when the very next operation will be to deallocate the object, thus making any messaging behavior undefined. That you can message the deallocated object in this particular case is merely coincidence. – bbum Feb 08 '11 at 00:37
  • So, I've not just mention the same ? Thanks for -1 :) – Martin Babacaev Feb 08 '11 at 00:40
  • Meh. Misread it; the last part went through my monkey skull as "if you can message it, it must have a retain count of 1" to imply that it magically wasn't deallocated. Sorry. Fixed the vote. – bbum Feb 08 '11 at 01:05