Retain Cycle in ARC
Asked Answered
P

3

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?

Pahari answered 9/10, 2012 at 14:34 Comment(1)
A zombie does not occur because of a retain cycle.Maxima
E
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.
Edelman answered 9/10, 2012 at 14:38 Comment(3)
Will the retain cycle cause memory leak in ARC ?Pahari
@Pahari Absolutely! Retain cycles are not ARC-specific, they will cause memory leaks in both ARC and non-ARC scenarios.Edelman
We could avoid them from causing memory leaks as I have explained in the comments to @Simon_Germain's answer.Eboat
F
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;
Fanion answered 9/10, 2012 at 14:37 Comment(5)
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.Eboat
The heading "Avoiding retain cycles rule #4: use "close" methods to break cycles" at 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.Eboat
Impossible might be a bit exaggerated, but let's just say it's not exactly trivial. Nothing is impossible.Fanion
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.Eboat
@Eboat that is exacswer i've been looking for!Autogenesis
C
0

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

Corn answered 11/7, 2016 at 1:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.