-3

I have a query in MRC in iOS & I am a little bit confuse. Suppose I have two objects ObjectA & ObjectB of the same type with below retain count

  1. ObjectA : retain count is 1
  2. ObjectB : reatin count 0

Now I am performing operation

ObjectB = [ObjectA retain];

Can anyone tell me what would be retained count of ObjectA & ObjectB?

As per my knowledge retain count of ObjectA = 2 & ObjectB = 1.

Please correct if I am wrong. If we are going to perform the copy operation, then what should be retained count.

Gagan_iOS
  • 3,638
  • 3
  • 32
  • 51

2 Answers2

2

First of all you have to understand, that objectA and objectB are not (Objective-C) objects. They are references to objects. (Objects have retain counts, not references to objects.)

So, your situation is correctly:

  • objectA points to an object that has a RC of 1.
  • objectB points to an object that has a RC of 0.

The second sentence is a paradox: There is never an object with RC 0, because reaching a RC 0 would deallocate the object. So there is no object anymore. (In practice a RC of 0 is never reached, because the object is deallocated when the RC is going to be 0. But this is an implementation detail and therefore not important.)

The statement …

objectB = [objectA retain];

… increases the RC of the object*, objectA points to. The return value of -retain is the value of the receiver pointer (objectA). This reference is then assigned to objectB. Therefore objectB – still being a reference – points to the same object, objectA points to. Since RCs are owned by the object, there is only one object and only one RC. It is 2.

Remark* Even it is documented that -retain increments the RC, this is not always that way. There are objects with eternal liefe time, having a virtual marker RC. However, I will keep the answer simple, so we assume that every execution of -retain increments the RC. But try this:

    id ref = @"RC";
    NSLog(@"%lu", [ref retainCount]);
    [ref retain];
    NSLog(@"%lu", [ref retainCount]);

You get:

2017-04-01 22:09:21.214 reftest[74967:8550738] 18446744073709551615
2017-04-01 22:09:21.215 reftest[74967:8550738] 18446744073709551615

Something increased? No.

But for the same reason you should never think in absolute values of RC ("a RC of 1"), but in changing a value at a location in source code: After a retain the RC is usually greater by 1 than it has been before. After a release the RC is usually less than 1 it has been before. Calculating a absolute value you have to consider all strong references to that object, what is impossible. And it is meaningless, because it is the strength of RC, that you think reference by reference instead of all references together.

Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • Your answer was good, clear, and easy to understand until you got to your "remark" bit. I have a very solid understanding of MRC, and I can't really make any sense of that paragraph. – Duncan C Apr 01 '17 at 19:51
  • @Amin thanks, could you please explain your *Remark*? I am unable to get? – Gagan_iOS Apr 01 '17 at 19:55
  • @DuncanC Gagan_iOS: You cannot say that an object has a specific RC. To make such a calculation you have to know *all* strong references to that object including internal references that might exist. This is impossible and makes no sense, because it is the strength of RC that you can scope the RC locally reference by reference. (You release, what you retained. You do not overall calculations.) It is a good habit to write RC relatively, i. e. +1, +2, … instead of 1, 2, … to express this. Mathematically it is the same. – Amin Negm-Awad Apr 01 '17 at 19:56
  • Maybe you did not understand the first sentence. Simply try this: Print the reference count of `@"RC"`. (This is an string object.) Then retain it and print it again. Do you see the remarkable values? – Amin Negm-Awad Apr 01 '17 at 20:00
  • Added some explanation. And corrected the "must not" to a "is not". (My fault, lost in translation.) – Amin Negm-Awad Apr 01 '17 at 20:14
  • In general it's safer not to speak about retain count at all and speak only about ownership. By calling `retain`, you don't increment anything, you create an ownership relationship. If there are no owners, the object is deallocated. – Sulthan Apr 01 '17 at 20:41
  • That's true. But you can call it "ownership count". And when you look at it locally (always in relation to one reference), it becomes clear that the only meaningful OC is 1 (or 0 …). And this means: There is an ownership (or not). Moreover I would say that *If there are no owners, the object is deallocated* is said too much. Nobody should care about deallocation, but about his ownerships. However, the Q specifically deals with RC. – Amin Negm-Awad Apr 01 '17 at 20:43
0

Your question doesn't really make sense.

First, a comment about variable names: You should be using variable names that start with lower case letters.

If you have an object in ObjectA and an object in ObjectB and the object in ObjectB's retain count reaches zero, it gets deallocated immediately, and no longer exists. ObjectB is now a "zombie" (A pointer to a deallocated object.) If you try to do anything with ObjectB once it's retain count reaches zero, you may crash, or the system may store a different object in that memory and your code may actually point to the completely wrong object.

When you execute the line:

ObjectB = [ObjectA retain];

...then the variable ObjectB now also points to ObjectA, and you've increased the retain count on your ObjectA object to 2. (ObjectB and ObjectA are now the same object, with a retain count of 2.)

Duncan C
  • 128,072
  • 22
  • 173
  • 272