9

I have never worked on non ARC based project. I just came across a zombie on my ARC based project. I found it was because of retain cycle.I am just wondering what is a retain cycle.Can

Could you give me an example for retain cycle?

j0k
  • 22,600
  • 28
  • 79
  • 90
Raj
  • 1,119
  • 1
  • 15
  • 32

3 Answers3

24

A retain cycle is a situation when object A retains object B, and object B retains object A at the same time*. Here is an example:

@class Child;
@interface Parent : NSObject {
    Child *child; // Instance variables are implicitly __strong
}
@end
@interface Child : NSObject {
    Parent *parent;
}
@end

You can fix a retain cycle in ARC by using __weak variables or weak properties for your "back links", i.e. links to direct or indirect parents in an object hierarchy:

@class Child;
@interface Parent : NSObject {
    Child *child;
}
@end
@interface Child : NSObject {
    __weak Parent *parent;
}
@end


* This is the most primitive form of a retain cycle; there may be a long chain of objects that retain each other in a circle.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
11

Here's what a retain cycle is: When 2 objects keep a reference to each other and are retained, it creates a retain cycle since both objects try to retain each other, making it impossible to release.

@class classB;

@interface classA

@property (nonatomic, strong) classB *b;

@end


@class classA;

@interface classB

@property (nonatomic, strong) classA *a;

@end

To avoid retain cycles with ARC, simply declare one of them with a weak reference, like so:

@property (nonatomic, weak) classA *a;
Simon Germain
  • 6,834
  • 1
  • 27
  • 42
  • Impossible to release? It could get released if we are careful to re-assign some other object for one of those properties breaking the chain right? I'm specifically asking because I've heard impossible to release many a time. – trss Jun 26 '13 at 11:05
  • The heading "Avoiding retain cycles rule #4: use "close" methods to break cycles" at http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html seems to confirm that it is possible to break retain cycles. It is definitely better to avoid but where it creates complexity otherwise, it could still be used but with care to break it before they create a memory leak, thus avoiding the leak. – trss Jun 26 '13 at 12:09
  • Impossible might be a bit exaggerated, but let's just say it's not exactly trivial. Nothing is impossible. – Simon Germain Jun 26 '13 at 17:48
  • Why I stressed that it is not impossible is because, when many people say impossible, someone trying to get a concrete grasp on such a loopy concept would find it hard to be certain of their understanding of it like it happened to me. Also, it is trivial to break the cycle. Just a simple reassignment would break it! If `foo.bar = bar; bar.foo = foo;` creates a retain cycle, a simple `foo.bar = baz;` would break it and no leak would be created. Right? This is my understanding. – trss Jun 26 '13 at 18:41
  • @trss that is exacswer i've been looking for! – Evgeniy Kleban May 29 '15 at 10:08
0

This is swift, but here's an interactive demo of retain cycles in iOS: https://github.com/nickm01/RetainCycleLoggerExample

Nick McConnell
  • 821
  • 8
  • 28