0

With ARC enabled I have a property

  @property (strong, nonatomic) NSMutableArray *arr;

I Allocate it as

  self.arr = [NSMutableArray array];

I have a custom object ERSearchView, I allocate it and add it to the arr

  ERSearchView *SV = [[ERSearchView alloc] initWithDelegate:nil];
  [arr addObject:SV];

In my search view I have overridden the dealloc method, because it seems that the search view isn't getting released:

- (void)dealloc {
  self.delegate = nil;
  NSLog(@"deallocated search view");
}

This isn't getting called when I pop my view controller. But if I nil the arr variable in the view controller's dealloc I see the log message that the search view has been deleted.

Can anyone explain how is this possible that objects inside arr aren't getting released though the view controller is 100% released since I have "did dealloc" message in its dealloc?

Kazuki Sakamoto
  • 13,929
  • 2
  • 34
  • 96
Eugene
  • 10,006
  • 4
  • 37
  • 55
  • i think you are missing the [super dealloc] in your dealloc method. and try to avoid accessors in your init and dealloc method, instead use iVars – CarlJ May 30 '12 at 14:52
  • 3
    With ARC enabled you can't directly call `dealloc`, even within the scope of sending the message to your superclass. – Eugene May 30 '12 at 14:53
  • You didnt called [super dealloc] in the override of dealloc, but according to me it's not because you released a container that all what he contained is released ... – John Smith May 30 '12 at 14:54
  • My normal approach to figuring out this kind of thing has been to use Instruments to look at the object's retain count history. I don't know how well that works with ARC. I suppose I should find out. :) – Phillip Mills May 30 '12 at 14:55
  • NSMutableArray retains the objects. Who owns your array (ie. self.arr)? And is the array being properly released? – David V May 30 '12 at 14:55
  • @JohnSmith, you can't call `dealloc` directly with ARC enabled. See my previous comment. – Eugene May 30 '12 at 14:57
  • @PhillipMills Thanks, but the issue is that with ARC enabled all the retain-release routine must be done automatically and it doesn't appear to be happening. – Eugene May 30 '12 at 14:58
  • @DavidV Thank you, I know that NSMutableArray retains its objects, but the point is that it should get implicitly released when my view controller's dealloc method gets called. UIViewController subclass owns the `arr`. And no, apparently it isn't getting properly released, that's the reason I created this post :) – Eugene May 30 '12 at 14:59
  • @Eugene -- So, you're saying Instruments doesn't report the effect of the ARC memory management? – Phillip Mills May 30 '12 at 15:01
  • 1
    Are you sure that your view controller is being deallocated? iOS does not deallocate views when the user leaves the view, and instead sends -viewWillUnload. Also, is it possible that some other class is retaining your array? It appears to be a public property. – David V May 30 '12 at 15:02
  • It's a private property and as I said the view controller is getting released, since I have overridden its dealloc and put in the "did dealloc message" which gets called when I pop the controller. – Eugene May 30 '12 at 15:09
  • @PhillipMills I'm not sure how to debug such behavior with instruments. I mean I know how to use Leaks, but that's about it. Anyways, this seems like an easy issue that must not require additional debugging with heavy artillery of instruments. – Eugene May 30 '12 at 15:23
  • @Eugene, Instruments is a good tool for this problem. You can see which code retains your objects. Also, it might help to have more source code for us on Stack Overflow. – David V May 30 '12 at 15:34

1 Answers1

1

Foundation collection classes such as NSArray, NSDictionary, etc. retain (or have a strong reference to, in ARC-speak) the objects they contain. So as long as the array hasn't been deallocated, the objects it refers to, including your view instance, should still be in memory.

It sounds as though you were leaking the array previously by not setting the property to nil in the controller's dealloc method. When an object declares a property as strong, it's responsible for the nilling the reference in its dealloc implementation to avoid this kind of leak.

jlehr
  • 15,557
  • 5
  • 43
  • 45
  • Really? I mean really you need to nil the strong variables in ARC enabled environment? O_O I thought that was made automatically. – Eugene May 30 '12 at 16:08
  • I'm sorry for asking this again, but could you please provide any reference to any document where I could read about this? I really appreciate your answer. – Eugene May 30 '12 at 16:09
  • It helped!! I'm so grateful, thank you so much! You are a life savior, I was going to switch to manual memory management. Thank you! – Eugene May 30 '12 at 16:21
  • 2
    I think this is only needed when running with NSZombie enabled. See http://stackoverflow.com/questions/8857518/arc-with-zombies-why-do-objects-in-instance-variables-not-get-released-when-ow – GBegen May 30 '12 at 17:08
  • 1
    @Eugene switching to Manual Memory Management is a really bad idea. Learn the semantics of ARC and it will save you tons of trouble. `strong` implies ownership, and so long as at least one object claims ownership of a child object, that child object stays in memory. You must release ownership on your own (or if it's just an ivar, this gets done for you in all your dealloc methods which are created for you by the compiler… naturally, if you override the compiler, you need to handle this yourself). – jbrennan May 30 '12 at 17:10
  • 1
    @Eugene Here's Apple's reference document on ARC: [Trasitioning to ARC Release Notes](http://www.google.com/url?sa=t&rct=j&q=transitioning%20to%20arc%20release%20notes&source=web&cd=1&ved=0CE4QFjAA&url=http%3A%2F%2Fdeveloper.apple.com%2Flibrary%2Fios%2F%23releasenotes%2FObjectiveC%2FRN-TransitioningToARC%2F_index.html&ei=OsDGT5KCMciL0QG1gqStCw&usg=AFQjCNE17Vky3OsDv6jcESIVf1Hu6qB8aw&sig2=bVxVBbseoQSQcTxNOTw2Ww) – jlehr May 31 '12 at 00:51
  • @GBegen I actually was wrong with accepting this answer. Begen you are absolutely correct, this behavior was caused by NSZombieEnabled option turned on. Thank you very much, if you'd add this as an answer I'd accept it. – Eugene Jun 29 '12 at 13:06