Retain Cycle in iOS

ref – http://blog.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/
http://stackoverflow.com/questions/15266367/why-isn-t-my-weak-reference-cleared-right-after-the-strong-ones-are-gone?rq=1
http://www.quora.com/Objective-C-programming-language/What-is-the-difference-between-a-strong-and-weak-pointer

Pointers are automatically created with strong references; they are automatically retained. In this case, the strong keyword is implied when creating pointers, though you can use it if you want.

However there are times when you don’t want to retain an object (i.e. increase its reference count). To do this, you use the weak keyword when creating the pointer. Your pointer will still point to the object, but if that object is destroyed then using the pointer will cause a program error.

Note: In Objective-C every object has a reference count (i.e. the number of strong references to the object). i.e alloc, retain, new, dot retain,

In our case below, strongPtr points to newly allocated NSString object. Then it points away to another newly allocated NSString object. the original NSString object “myTestText” has no one pointing to it, even though it exists in memory because it does have a retain count of 1. Its just hanging out in memory space. Thus, ARC will either send a release or auto-release to it.

If ARC send release, weakPtr will display nil. If auto-release, then weakPtr may still display the address of the “myTestText”:

  • Strong variables will retain the value they point to.
  • Weak variables won’t retain their value and when the value is deallocated they will set their pointer to nil (to be safe).
  • Unsafe unretained values (as you probably can read by the name) won’t retain the value and if it gets deallocated they do nothing about it, potentially pointing to a bad piece of memory

When you’re working with garbage collection (10.5+), a weak reference is created by prefixing a variable declaration with __weak. When you assign to that variable, the GC (if enabled) keeps track of the reference and will zero it out for you automatically if all strong references to the referenced object disappear. (If GC is not enabled, the __weak attribute is ignored.)

Thus, you can safely modify the above answer to play nicer with garbage collection (currently on 10.5+, and perhaps someday on iPhone) as follows: (See the related Apple docs.)

@property (nonatomic,assign) __weak Row *yCoord;

To quote Chris Hanson (where you can find more detailed information):

“By prefixing an instance variable declaration with __weak, you tell the garbage collector that if it’s the only reference to an object that the object should be considered collectable.”

I’d clarify that by saying “if there are no non-weak references to an object”. As soon as the last strong reference is removed, the object may be collected, and all weak references will be zeroed automatically.

Note: This isn’t directly related to creating weak references, but there is also a __strong attribute, but since Objective-C object variables are strong references by default, it is generally used only for raw C pointers to things like structs or primitives that the Garbage Collector will not treat as roots, and will be collected from under you if you don’t declare them as strong. (Whereas the lack of __weak can cause retain cycles and memory leaks, the lack of __strong can result in memory stomping and really strange and insidious bugs that occur non-deterministically and can be quite difficult to track down.)

Why would you use a weak reference?

Well, one reason is if you have objects in parent-child relationships where the parent keeps pointers to its children and every child keeps a pointer to its parent. The potential with this structure is that you could no longer need your parent object and XCode will implicitly release it, but because its children keep a reference to it, the parent and its children can remain in memory even though you no longer have a way of accessing them. This is called a retain cycle.

To avoid the retain cycle, the children objects should only maintain a weak pointer to their parents. The reason for this is that when the parent is told to destroy itself, the children would be destroyed first so there is no chance they could access their parent after it had been destroyed.

NSTimer

If you create an NSTimer object on a view controller, be sure that invalidate is called on it when dismissing the view controller, otherwise it will retain self.

Observers/NSNotificationCenter

If you add an observer to NSNotificationCenter, make sure you remove all observers when dismissing the view controller, otherwise they will retain self.

Blocks

You should not call [self doSomething] from inside a block, this can easily lead to the block capturing a reference to self. Instead, make a weak reference to self:

BAD:

GOOD

Delegates

if you use

inside the view controller, check the delegate property on someObj is weak.

Once you’ve made your fixes, check that dealloc is getting hit and the allocations no longer increase endlessly.