Note that there are some explanatory texts on larger screens.

plurals
  1. POStrange memory leak in Window:addSubView
    text
    copied!<p>first of all sorry for my English :-) not so good.</p> <p>I have a strange memory leak with the following code (code after the explanation). I have a class, FLWaitingView. It is a simple view with a waiting indicator (plus a view with background), used to say to the user "wait for the data to be loaded". It has two simple methods: show and dismiss. In the show method, I find the main Application Window and add the subviews (the waiting view and a background view, with different animations). In the dismiss method, I remove it from superview. In every show, I verify that the view isn't already visible using a static bool var (is_visible).</p> <p>The strange thing is this: In the dismiss method, I use:</p> <pre><code>[self.view removeFromSuperview]; [self.waitingView removeFromSuperview]; </code></pre> <p>to remove the two views from the Window, to avoid them to be retained. They are correctly removed, I can verify this with NSLog (for cicle on each window subview). But, in INSTRUMENTS, using the "mark heap" function, I see that in every single reload (new instance of FLWaitingView, then show, then dismiss) the old instance remains in memory and continues to increase memory usage. Obviously is not a problem of the calling code, because I correctly release the object:</p> <pre><code>//CALLING CODE //customWaitingView is a property retained self.customWaitingView = [[[FLWaitingView alloc]init]autorelease]; [self.customWaitingView show]; </code></pre> <p>Moreover, and I think that this is the most important information, if I move the view dismission in another method, called by a selector, the leak disappear!!!</p> <p>Now I show the "wrong" code and, after, the "correction". I would like to understand why it happens.</p> <pre><code>- (void)show { if (!is_visible){ id appDelegate = [[UIApplication sharedApplication] delegate]; UIWindow *window = [appDelegate window]; self.waitingLabel.text = @"Attendere"; self.view.alpha = 1.0; self.waitingView.alpha = 1.0; [window addSubview:self.view]; [window addSubview:self.waitingView]; [self.waitingIndicator startAnimating]; self.view.frame = window.frame; self.waitingView.center = window.center; // "Pop in" animation for alert [self doPopInAnimationWithDelegate:self]; // "Fade in" animation for background [self doFadeInAnimation]; is_visible = YES; } else { NSLog(@"FLWaitingView %@ already visible, do nothing", self); } } - (void)dismiss { [UIView beginAnimations:nil context:nil]; self.view.alpha = 0.0; self.waitingView.alpha = 0.0; [UIView commitAnimations]; [self.waitingIndicator stopAnimating]; //here is the problem [self.view removeFromSuperview]; [self.waitingView removeFromSuperview]; is_visible = NO; } </code></pre> <p>the code above is the "wrong" one, but if I add </p> <pre><code>[self performSelector:@selector(alertDidFadeOut) withObject:nil afterDelay:0.5]; </code></pre> <p>in the dismiss method and a new method (obviously removing the redundant code from dismiss method):</p> <pre><code>- (void)alertDidFadeOut { //here the memory is correctly released [self.view removeFromSuperview]; [self.waitingView removeFromSuperview]; is_visible = NO; } </code></pre> <p>the memory is correctly released. Why?????? Thank you in advance</p> <p>Fabio</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload