-1

I have learned manual memory management in Objective-C and every article said: "When the retain count of an object drops to 0, the dealloc method is called and the object is destroyed". And nothing more.

But there is no answer for several questions: Can I drop the retain count below 0? Is it possible to call [object release] several times in a row, before the object dies, and cause the retain count to drop below 0? And if I've done so, will the Universe still exist?

Google gives me nothing, like: "Why would you even ask this question? Nobody cares. Go and read about memory management once more."

jscs
  • 62,161
  • 12
  • 145
  • 186
WantToKnow
  • 1,367
  • 2
  • 10
  • 18
  • 1
    Try searching for "over releasing objective c" – A O Sep 27 '16 at 14:10
  • Actually, what I should have said is: What happened when you tried it? Your question is easily answered by experiment. – matt Sep 27 '16 at 14:47
  • No, universe will not exist any more. You will get crash BAD_ACCESS somewhere. Haven't you tried it by yourself? Quite admirable, that you are learning about manual memory management, it will help you understand thing from inside. But it is quite unsafely and in modern projects doesn't used. – Cy-4AH Sep 27 '16 at 15:32
  • 1
    You might be interested in [Objects' retain counts never go below 1 despite deliberately overreleasing](http://stackoverflow.com/q/4927613) – jscs Sep 27 '16 at 17:23
  • 3
    The current runtime (going back several releases, at least) never drops the count to zero. Instead, when it would have decremented to zero, it just skips that part and calls `dealloc`. See the numerous questions asking why `retainCount` reports 1 for a `dealloc`ed object. – Avi Sep 27 '16 at 17:27

2 Answers2

2

If you call release when the retain count is 1, dealloc is immediately called. So the retain count doesn't ever even get to 0.

Further calls to release will cause a runtime crash as you would be dereferencing a deallocated object.

So no, the universe won't exist at that point :)

Gabriele Petronella
  • 102,227
  • 20
  • 204
  • 227
-3

A retain count can be 0 or higher but never less. When an object is allocated heap memory (alloc init) the retain count is set to 1. You can then increase the retain count by calling retain on it (as far as I'm aware an unlimited number of times but I could be wrong).

Calling release simply decreased the retain count by 1. The system then periodically checks the retain counts of objects and deallocates any with a count of 0.

Calling release on an already deallocated object is the same as calling any method on a NULL object and should simply return NULL or void. However, if you are explicilty managing heap memory then you should be VERY aware of what you're doing.

Some interesting points:

Why can a retain count be more that 1?

This is so that an object isn't released whilst it is still required by something else. E.g. say you have pet owner and vet. A pet instance is owned by an owner instance. The owner goes to a vet instance and the vet takes ownership of the pet also. For a period of time pet has two owners and therefore (if retain has been called) has a retain count of 2. Lets say that the owner is then released before the vet has finished with the pet; if everything has been done properly the pet wont be deallocated it will simply have its reatain count decreased to 1 by the call to release from owner. The vet can then finish with the pet, call release and the pet will be deallocated.

ARC

As I'm sure you're aware this has all been replaced by Automatic Reference Counting. As developers we now have to simple be aware of the type of relationship an object has with another.

Therefore if you create an object now it will be deallocated when it fall out of scope unless it has a strong relationship (is owned) by another object. You can still get reatain cycles where two objects have strong relationships to each other and therefore never qualify for deallocation.

Appologies for the very long winded answer but memory management is a core part of application programming and is very interesting.

Rob Sanders
  • 4,398
  • 3
  • 26
  • 52
  • 2
    "Calling release on an already deallocated object is the same as calling any method on a NULL" Only if the pointer was actually set to `nil`. Sending `release` to a deallocated object is programmer error: undefined behavior. – jscs Sep 27 '16 at 17:17
  • 3
    This answer starts very wrong. The retain count can **never be 0**. The system **does not** periodically check anything. Calling a method on a deallocated object is undefined behavior and will oft crash, it is **not at all** like calling any method on `NULL`. The `vet`/`owner`/`pet` analogy is spot on though. – bbum Sep 27 '16 at 18:12