Objects' retain counts never go below 1 despite deliberately overreleasing

673 views Asked by At

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?

6

There are 6 answers

5
Catfish_Man On BEST ANSWER

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.

0
jon On

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.

0
Thomson Comer On

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.

8
Martin Babacaev On

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.

0
bbum On

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.

0
AudioBubble On

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