1

When I pop a UIViewController instance off of my UINavigationController, I find that its properties remain (NSTimers keep timing, AVAudioPlayers keep playing, etc.). I'm wondering what's wrong with my approach?

I push the UIViewController instance onto the UINavigationController this way:

- (IBAction)buttonPressed:(id)sender {
    UINavigationController *nc=[self navigationController];
    NewViewController *nvc=[[NewViewController alloc] init];
    [nvc setNameToUse:[self nameToUse]];
    [nc pushViewController:nvc2 animated:YES];
}

The NewViewController has a sub-viewcontroller, that is added via NiewViewController's viewDidLoad method:

self.mySubViewController=[[SubViewViewController alloc] initWithName:self.nameToUse];
self.mySubViewController.view.frame=CGRectMake(0,
                                           0,
                                           self.mySubViewController.view.frame.size.width,
                                           self.mySubViewController.view.frame.size.height);
[self.view addSubview:self.mySubViewController.view];

It's the properties of SubViewController that don't go away when NewViewController is popped. One of these in particular is a timer, declared as follows:

@property (nonatomic) NSTimer *aTimer;

Any advice on this would be terrific. I'm hoping that by solving this issue, the crashes that have been happening once in a while (after the app has been running for 45 or so minutes) will stop! Or at least I'll have a better idea of what's causing them... :) Thanks for reading.

Rogare
  • 3,234
  • 3
  • 27
  • 50
  • Instead of making `mySubViewController` a property of your view controller try adding it as a child view controller. – ChrisH Sep 05 '13 at 14:16
  • Thanks for the comment. I did do this, but it was my usage of NSTimer which was the culprit. – Rogare Sep 07 '13 at 16:01

2 Answers2

2

NSTimer retains it's target, if you are passing self (your SubViewViewController) then you'll be creating a retain cycle between the view controller and the timer.

Steve Wilford
  • 8,894
  • 5
  • 42
  • 66
  • Yup, that appears to be it! I temporarily dropped the timer and now the AVAudioPlayer stops playing when NewViewController is popped. Is there an alternative way to use the timer that won't cause the retain cycle? – Rogare Sep 07 '13 at 15:59
  • This thread appears to be exactly what I need: http://stackoverflow.com/questions/3478361/best-time-to-invalidate-nstimer-inside-uiviewcontroller-to-avoid-retain-cycle. – Rogare Sep 07 '13 at 16:07
0

Simply adding SubViewController's view to ViewController's will not correctly pass events.

You need to correctly implement UIViewController child containment, as such:

So your second code block should be something like:

[self addChildViewController:self.mySubViewController];
[self.view addSubview:self.mySubViewController.view];
[self.mySubViewController didMoveToParentViewController:self];
Arie Litovsky
  • 4,893
  • 2
  • 35
  • 40