4

I have an AViewController, if I create BViewController as an instance variable like this

@interface AViewController ()
{
    BViewController *bVC;
}
@end

then push

- (void)push {
    bVC = [[BViewController alloc] init];
    [self.navigationController pushViewController:bVC animated:YES];
}

Dealloc method won't be called when BViewController pop.

Both viewcontrollers are almost empty, I mean there are no NSTimers, blocks or network requests. I guess a strong reference cycle exists in AViewController, but can't figure out the cycle.

So, can anyone help me about this, thanks!

xuning0
  • 85
  • 8
  • So, question, Ning, how did you test the dealloc, did you NSLog to check it to see if it was not being called, I'm just wondering because it seems very strange that it wouldn't be called. – Larry Pickles Aug 28 '15 at 03:41
  • Ning, I just tried this out on one of my apps that's close to production, and POPing the viewcontroller doesn't call dealloc, I've never paid attention to this before, but that's sort of odd. I also changed it to an IVAR like you have yours, and I'm getting the same behaviour. – Larry Pickles Aug 28 '15 at 03:47
  • The view controller is not being deallocate because there is still a reference to it. As long as `bVC` has a strong reference, it can't be deallocated. – rmaddy Aug 28 '15 at 03:47
  • yep, rmaddy, you are right, i just declared it again in the method only and dealloc is called, – Larry Pickles Aug 28 '15 at 03:48
  • @rmaddy what are the implications of having this as an IVAR vs otherwise? it's actually calling dealloc when the PUSH occurs after pushing and popping one time, totally backwards – Larry Pickles Aug 28 '15 at 03:49
  • here's an SO on this, Ning, not sure if this will help but it's giving me what I needed :http://stackoverflow.com/questions/7093136/who-calls-the-dealloc-method-and-when-in-objective-c?rq=1 I came to c languages after retain release was a deal with ios so , this so answer explains some good stuff – Larry Pickles Aug 28 '15 at 03:53
  • @Larcerax As you say, I write `NSLog(@"========= %@ dealloc", NSStringFromClass(self.class))` in dealloc method in BaseViewController. So I can clearly see if a viewcontroller is dealloc as it should be :) – xuning0 Aug 28 '15 at 04:17
  • yep, you are right, Ning, that's perfect, you should read rmaddy's answer, this is all good stuff, Im glad you asked this question, I will now be using IVARs a lot less – Larry Pickles Aug 28 '15 at 04:23
  • You can try to make a weak reference: __weak BViewController *bVC; – Harrison Xi Aug 28 '15 at 04:34

1 Answers1

3

This is basic memory management 101.

An object is deallocated only after there are no more strong references to the object.

Your ivar bVC has a strong reference to the view controller. Pushing it adds another. Then you pop it and it's back to just the one strong reference by bVC. So it doesn't get deallocated.

You can either avoid the ivar or set it to nil at some point so the view controller can be deallocated.

rmaddy
  • 298,130
  • 40
  • 468
  • 517