2

I'm facing an annoying issue and I can't find out why.

I have a UIViewController I present in modal like that :

interviewsViewController *interviewsVC = [[interviewsViewController alloc] initWithNibName:nil bundle:nil];
[interviewsVC setManagedObjectContext:_managedObjectContext];

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:interviewsVC];
[interviewsVC release];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];

Then when I dismiss the view controller like this :

- (void)dismissViewController
{
     [self dismissModalViewControllerAnimated:YES];
}

The dealloc gets called :

- (void)dealloc
{
    [_managedObjectContext release];
    [_interviewsArray release];
    [scrollView release];
    [pageControl release];
}

Once the view controller is dismissed, I send an memory warning via the iPhone Simulator Menu and the viewdidunload method gets called :

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.scrollView = nil;
    self.pageControl = nil;
}

But there's always an error EXC_BAD_ACCES on the self.scrollView = nil ... More specifically at this line :

@synthesize scrollView;

And I can't find out why ?

If I add a breakpoint on the line above this one, the scrollView is not a zombie or equal to 0x0 ...

Do you have an idea ?

PS : Here's the header :

#import <UIKit/UIKit.h>

@interface interviewsViewController : UIViewController <UIScrollViewDelegate>
{
    NSManagedObjectContext *_managedObjectContext;

    NSMutableArray *_interviewsArray;

    NSUInteger _fetchOffset;

    CGFloat _lastXValue;
}

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSMutableArray *interviewsArray;

//IBOutlet
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
@property (nonatomic, retain) IBOutlet UIPageControl *pageControl;

And I set the delegate of the scrollview in the XIB (not in the code).

Dabrut
  • 862
  • 1
  • 10
  • 25
  • does the Analyzer show any potential problems? – Max MacLeod Jan 12 '12 at 15:08
  • Nothing with the Analyzer Max – Dabrut Jan 12 '12 at 15:14
  • Your problem is that `-viewDidUnload` is getting called *after* your object has already been deallocated. When you set your property to nil, your synthesized setter method is attempting to release the old value, which is already garbage because you released it in `-dealloc`. You need to find out why the view management system is still sending messages to your deallocated controller, because that is actually your problem. – Jason Coco Jan 12 '12 at 15:32

1 Answers1

1

You need to release properly in dealloc-

Use-

- (void)dealloc {
      [_managedObjectContext release];
      [_interviewsArray release];
      self.scrollView = nil;
      self.pageControl = nil;

      [super dealloc];
}

ViewDidUnload also be used as that will be helpfull in case of low memory warnings.

rishi
  • 11,779
  • 4
  • 40
  • 59
  • Also, in `dealloc` and `viewDidUnload` the `super` call should be the last call in the method. – MishieMoo Jan 12 '12 at 15:14
  • @RIP : That's what I thought. But why in the template there's // e.g. self.myOutlet = nil; ??? – Dabrut Jan 12 '12 at 15:15
  • Refer following threads you will get your answer- http://stackoverflow.com/questions/2261972/what-exactly-must-i-do-in-viewdidunload, http://stackoverflow.com/questions/2844348/follow-up-viewdidunload-vs-dealloc-question – rishi Jan 12 '12 at 15:17
  • @MishieMoo : I agree for the dealloc method but in Apple's example, they call [super viewDidUnload] in first call. – Dabrut Jan 12 '12 at 15:19
  • Calling order depends on the task that super class is performing, If you want some more details then you can check following thread- http://stackoverflow.com/questions/2365440/iphone-super-viewdidunload-calling-order – rishi Jan 12 '12 at 15:24
  • @RIP : OK I now understand. I think the issue was the [super dealloc]. Cause I was dismissing the modalviewcontroller and then the dealloc was called before the viewdidunload. Now with the [super dealloc]. It works fine. Kudos to you. – Dabrut Jan 12 '12 at 15:26
  • This answer is wrong... you should implement *both* `-viewDidUnload` and `-dealloc` in managed memory situations. `-viewDidUnload` will only be called in low memory situations when the view is removed but the controller is still alive. Not implementing it could cause leaks. – Jason Coco Jan 12 '12 at 15:31
  • @JasonCoco- i haven't said that he need to implement only one method, release of an object needs to be done only at single place, Am i wrong in this? – rishi Jan 12 '12 at 15:34
  • @RIP You need to include `-viewDidUnload` because it's possible that when you get a memory warning the view will be released, then get recreated and `-viewDidLoad` is called again. So in `-viewDidUnload` you need to undo everything you setup in `-viewDidLoad`. – MishieMoo Jan 12 '12 at 15:37
  • Yes, it's wrong. You need to release any of your view stuff in both places. His problem is that for some reason his dead view controller is still receiving messages from the system, not in his memory management code. In his case it wouldn't result in a leak since he's using a property for the outlet, but you should clean up any of your view data in both `-viewDidUnload` and `-dealloc` or you risk leaking memory. – Jason Coco Jan 12 '12 at 15:38
  • @JasonCoco I don't need to use viewDidUnload method till now in my 2 yr experience, if i follow all the things in the right manner then it is rare that i will receive memory warning, and i might skipped the usage of this. So might be the issue occurs due to incomplete implementation of dealloc method. Anyways thanks for your comment, i will update above post. – rishi Jan 12 '12 at 15:46
  • Yeah, the bigger problem is that this answer will make it look like his issue has gone away, but his issue is still actually there, it's just not manifesting anymore but could easily crash again later in some other place. – Jason Coco Jan 12 '12 at 15:48