iphone - Strange memory leak in Window:addSubView -
first of sorry english :-) not good.
i have strange memory leak following code (code after explanation). have class, flwaitingview. simple view waiting indicator (plus view background), used user "wait data loaded". has 2 simple methods: show , dismiss. in show method, find main application window , add subviews (the waiting view , background view, different animations). in dismiss method, remove superview. in every show, verify view isn't visible using static bool var (is_visible).
the strange thing this: in dismiss method, use:
[self.view removefromsuperview]; [self.waitingview removefromsuperview];
to remove 2 views window, avoid them retained. correctly removed, can verify nslog (for cicle on each window subview). but, in instruments, using "mark heap" function, see in every single reload (new instance of flwaitingview, show, dismiss) old instance remains in memory , continues increase memory usage. not problem of calling code, because correctly release object:
//calling code //customwaitingview property retained self.customwaitingview = [[[flwaitingview alloc]init]autorelease]; [self.customwaitingview show];
moreover, , think important information, if move view dismission in method, called selector, leak disappear!!!
now show "wrong" code and, after, "correction". understand why happens.
- (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 alert [self dopopinanimationwithdelegate:self]; // "fade in" animation background [self dofadeinanimation]; is_visible = yes; } else { nslog(@"flwaitingview %@ visible, 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 problem [self.view removefromsuperview]; [self.waitingview removefromsuperview]; is_visible = no; }
the code above "wrong" one, if add
[self performselector:@selector(alertdidfadeout) withobject:nil afterdelay:0.5];
in dismiss method , new method (obviously removing redundant code dismiss method):
- (void)alertdidfadeout { //here memory correctly released [self.view removefromsuperview]; [self.waitingview removefromsuperview]; is_visible = no; }
the memory correctly released. why?????? thank in advance
fabio
your view isn't getting released expecting because @ moment you're releasing there still animations linked it. can release after animations finished.
your second method works because animation lasts less 0.5 seconds - releasing code called after view freed of animations.
proper way animate view either create animation , assign delegate or maybe bit more elegant soulution use block-based animation this:
- (void)dismiss { [[uiapplication sharedapplication] beginignoringinteractionevents]; [uiview animatewithduration: 0.15 animations: ^{ self.view.alpha = 0.0; self.waitingview.alpha = 0.0; } completion: ^(bool finished){ [self.waitingindicator stopanimating]; [self.view removefromsuperview]; [self.waitingview removefromsuperview]; is_visible = no; [[uiapplication sharedapplication] endignoringinteractionevents]; }]; }
Comments
Post a Comment