2

I'm starting to write the second version of our iPhone app and I'm trying to tidy up previous mistakes (as it's my first attempt at Objective-C). My question is related to "things I need to do when a UIViewController is destroyed", there seem to be a few contradictory answers out there and I want to make sure I understand correctly.

Couple of constraints:

  1. This code is for use with iOS 5 and iOS 6 devices
  2. I don't wish to register and deregister NSNotifications on viewWillAppear and viewWillDisappear because the UIViewControllers need to receive notifications even if they can't be seen by the user.
  3. I'm using a StoryBoard rather than separate nib files.

So considering the above constraints, are the following statements true?

  1. IBOutlets connecting the storyboard to the UIViewControllers should be weak, the strong reference will be created behind the scenes.
  2. Because the IBOutlets are weak I shouldn't need to nil them out in low memory situations
  3. I shouldn't use viewDidUnload because it's being deprecated instead I should use didReceiveMemoryWarning. In this situation I only need to nil out strong properties (that can re-calculated)
  4. It's acceptable to register for NSNotifications on viewDidLoad.
  5. Because I wish to continue receiving notifications when the view is hidden, the best place to unregister them is in dealloc, there's no benefit in also unregistering them in didReceiveMemoryWarning.

Thanks for your help,

Dan

Dan Rowlands
  • 1,382
  • 12
  • 18

2 Answers2

4

IBOutlets connecting the storyboard to the UIViewControllers should be weak, the strong reference will be created behind the scenes.

No. NSKeyedUnarchiver (NSCoder) does not change the storage qualifiers associated with user-created outlets. You keep them weak because you don't ever explicitly alloc and init IBOutlets, therefore you do not "own" them in the cocoa sense of the word.

Because the IBOutlets are weak I shouldn't need to nil them out in low memory situations

Not true at all. Zeroing weak references zero out in dealloc, not in low memory situations. Apple expects you to do that by explicitly releasing strong outlets to handle memory warnings.

I shouldn't use viewDidUnload because it's being deprecated instead I should use didReceiveMemoryWarning. In this situation I only need to nil out strong properties (that can re-calculated)

Yes, but as for the replacement for -viewDidUnload, dealloc serves that purpose.

It's acceptable to register for NSNotifications on viewDidLoad. Because I wish to continue receiving notifications when the view is hidden, the best place to unregister them is in dealloc, there's no benefit in also unregistering them in didReceiveMemoryWarning.

Absolutely.

CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • Thanks for the response, curious about your reply to point 2. I didn't think I would need to nil out weak references because they wouldn't keep the associated object alive. I'd assumed that as soon as an object lost all of it's strong references it would be destroyed. – Dan Rowlands Mar 01 '13 at 14:34
  • Sorry, in addition to that, if I zeroed out my weak IBOutlets during a low memory situation how would I get the references to the UI objects back? – Dan Rowlands Mar 01 '13 at 14:35
  • 1
    Indeed I don't agree with that point. nil-ing any weak reference will not free any memory whatsoever. – DaGaMs Mar 01 '13 at 14:37
  • It's acceptable to register for NSNotifications on viewDidLoad. -- make sure to do it only on the 1. call of viewDidLoad OR do it in viewDidUnload as well! – Daij-Djan Mar 01 '13 at 15:06
  • What I meant is that you cannot release weak outlets to free up memory. You explicitly free and recreate strong outlets. – CodaFi Mar 01 '13 at 15:08
  • 1
    Point #1: Specifically what is happening is the top most view in the scene is represented by self.view in the view controller. Self.view _is_ a strong reference. Since the top most view has a strong reference, subviews do not need to be strong to stick around. – memmons Mar 01 '13 at 15:11
  • @answerbot that's because the view is owned by the controller. It is not a user-created outlet. – CodaFi Mar 01 '13 at 15:15
1

I believe what you say is correct. Regarding IBOutlets and strong/weak references, see this thread.

As for notifications: unregistering them in didReceiveMemoryWarning seems pointless as they are not by themselves freeing any memory upon de-registration. Therefore you're right in deregistering them upon deallocation.

Community
  • 1
  • 1
DaGaMs
  • 1,521
  • 17
  • 26