2

In Apple's docs it says

You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn’t compiled using ARC.

Does this include UIKit and Framework delegates, for example, the parent of a UIPageViewController has the delegate UIPageViewControllerDelegate - does this have to be nilled in the dealloc?

Arun_
  • 1,806
  • 2
  • 20
  • 40
daihovey
  • 3,485
  • 13
  • 66
  • 110
  • I am assuming Yes, but have never seen it done in Apple's own example code. – daihovey Sep 27 '13 at 01:39
  • This question [has already been asked and answered as part of this closely related question](http://stackoverflow.com/questions/7906804/do-i-set-properties-to-nil-in-dealloc-when-using-arc). – Michael Dautermann Sep 27 '13 at 01:40
  • What do you mean by "the parent... has the delegate". What would be set to nil in which classes' dealloc implementation in this case? – Carl Veazey Sep 27 '13 at 01:44
  • @CarlVeazey Parent being a UIViewContoller, which adopts the UIPageViewControllerDelegate protocol, with an instance of a UIPageViewControlle. – daihovey Sep 27 '13 at 01:48

1 Answers1

2

When you have a relationship between the a parent controller and its view, where the parent controller acts as the views delegate, one of those relationships must not retain the other, otherwise you will have a retain cycle and a memory leak.

There are two ways to do this:

  • There first is to mark the delegate as __unsafe_unretained. If you do this you will need to manually nil out the reference in the dealloc of the controller.

  • The second is to use a weak reference. Most of ARC happens at compile time. This helps to save battery drain by reducing the CPU cycles that would otherwise occur with a garbage collector. However, for weak references, there's a run-time process that maintains a map of these variables, observes them, and nils them out as required. This is why weak references required iOS5.1 - its not just a compiler feature.

  • If you use too many weak references, it can be a performance overhead. In practice this will hardly ever be a concern.

Summary

  • No you don't need to manually nil it out if you use weak references. Check that you don't have a memory like via a retain cycle of strong references.
  • Only use __unsafe_unretained (aka 'assign') if you really have to.
  • The same rules apply for UIKit and framework classes. The nice thing is that they're very consistent.

Update

  • Correcting my dodgy comment: If your delegate goes away before the controller does, then you will need to nil it off the controller manually - thanks @borrden.
Jasper Blues
  • 28,258
  • 22
  • 102
  • 185
  • So in my example, the UIPageViewControllerDelegate is assigned, would this be nilled in the dealloc? – daihovey Sep 27 '13 at 01:51
  • Looking at the docs this property is already 'assign' scoped. (Old-style of weak). So Apple take care of niling it for you. https://developer.apple.com/library/ios/documentation/uikit/reference/UIPageViewControllerClassReferenceClassRef/UIPageViewControllerClassReference.html#//apple_ref/occ/instp/UIPageViewController/delegate . . so that means you don't. – Jasper Blues Sep 27 '13 at 01:54
  • 2
    Dangerously incorrect (or at least strangely worded). assign is *not* the "old-style of weak", it is the same as unsafe-unretained. See section 4.1.1 http://clang.llvm.org/docs/AutomaticReferenceCounting.html – borrrden Sep 27 '13 at 01:56
  • 2
    If you set an unsafe unretained delegate, you need to nil it, as you noted. Your comment seems to contradict what you said in your answer. – borrrden Sep 27 '13 at 02:13
  • @daidai - Note that borrden is right. If your delegate goes away before the controller does, then you need to nil it off the controller. – Jasper Blues Sep 27 '13 at 04:33