1

Its very common question everybody familiar with, but I'm still not understand it fully.

If Object A owns (have a strong property of) Object B, and Object B have a strong property of object A, there is retain cycle, and no object can be released and there is a memory leak.

But, what if Object A instead will point for Object C instead of Object B, therefore another address in memory?

As far as i know, strong properties do something like follow:

- (void)setObject:(id)newObject{
if (_newObject == newObject){
return; //
}

NSObject *oldObject = _newObject;
_newObject = [newObject retain];
[oldObject release];
}

So, what if we point instead for Object C, isn't in that case memory for Object B will be released? What if both Objects (A and B) will instead set nil object? Is there still would be retain cycle with memory leak? With old value "floating" somewhere in memory?

I know, that has been discussed many times, but i still can't get "whole picture" in my head. I would appreciate any clarification in that matter.

bbum
  • 162,346
  • 23
  • 271
  • 359
Evgeniy Kleban
  • 6,794
  • 13
  • 54
  • 107
  • The allocation instruments has tools to help aid in cycle detection. I suggest you explore said tools. If you want to write example code to play with, create your own subclass of `NSObject` so you don't run into static instances (like @"foo") or tagged pointers. – bbum May 29 '15 at 16:08

2 Answers2

3

The word you are looking for is "retain cycle".

The simplest retain cycle would be an object having a strong reference to itself. Very rare because it is rather pointless.

The most common case is A having a strong reference to B and B having a strong reference to A. A->B->A. You see the cycle?

The cycle can be any length A->B->C->D->E->F->G->...->A. It's a retain cycle, so nothing will be released. If you have just A->B->C->D->...->Z with no reference back to another object in the sequence, then there is no cycle. No cycle, no problem.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • so, if we have cycle A>B>A, and then we do A>C and B>D, with same strong reference, there would be no memory leak and therefore retain cycle? – Evgeniy Kleban May 29 '15 at 09:52
  • 1
    An object having a strong reference to itself is not rare there days, by the way, since objects in Swift can have closures as their properties, which catch a strong reference to `self` once you access any property or method of `self` inside that closure. Obj-C blocks can also cause retain cycles with `self`, as explained here: http://stackoverflow.com/questions/4352561/retain-cycle-on-self-with-blocks?rq=1 – Daniil Korotin May 29 '15 at 10:45
  • @EvgeniyKleban Both this answer and JeremyP's answer are correct. – bbum May 29 '15 at 15:59
3

If the question is "can you break a retain cycle by reassigning one of the properties?", the answer is yes. This applies equally if you assign nil to the property.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • if just one of the properties would be re-assigned - set to nil, it would be enough to get rid of retain cyrcle? – Evgeniy Kleban May 29 '15 at 11:12
  • 1
    yes. Because the cycle exists when both refer to each other. So if A -> B but B -> NIL, you have no cycle. But this is all academic, you should be using a strong A-> B and a weak B->A (or assign, but usually weak is appropriate). – Jess Bowers May 29 '15 at 15:53