прежде всего извините за мой английский :-) не очень хорошо.
У меня странная утечка памяти со следующим кодом (код после объяснения).
У меня есть класс, FLWaitingView. Это простое представление с индикатором ожидания (плюс представление с фоном), используемое для того, чтобы сказать пользователю «дождаться загрузки данных».
У него есть два простых метода: показать и отклонить.
В методе show я нахожу главное окно приложения и добавляю подпредставления (вид ожидания и фоновый вид с различными анимациями). В методе dismiss я удаляю его из superview.
В каждом шоу я проверяю, что представление еще не видно, используя статическую переменную bool (is_visible).
Странная вещь: в методе dismiss я использую:
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
чтобы удалить два вида из окна, чтобы избежать их сохранения. Они правильно удалены, я могу проверить это с NSLog (для cicle на каждом подпредставлении окна). Но в INSTRUMENTS, используя функцию «mark heap», я вижу, что при каждой перезагрузке (новый экземпляр FLWaitingView, затем показ, затем удаление) старый экземпляр остается в памяти и продолжает увеличивать использование памяти. Очевидно, это не проблема вызывающего кода, потому что я правильно освобождаю объект:
//CALLING CODE
//customWaitingView is a property retained
self.customWaitingView = [[[FLWaitingView alloc]init]autorelease];
[self.customWaitingView show];
Более того, и я думаю, что это самая важная информация, если я переместу отображение вида в другой метод, вызываемый селектором, утечка исчезнет !!!
Теперь я показываю «неправильный» код и, после, «исправление». Я хотел бы понять, почему это происходит.
- (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;
}
приведенный выше код является "неправильным", но если я добавлю
[self performSelector:@selector(alertDidFadeOut) withObject:nil afterDelay:0.5];
в методе dismiss и новом методе (очевидно, удаляющий избыточный код из метода dismiss):
- (void)alertDidFadeOut
{
//here the memory is correctly released
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
is_visible = NO;
}
память освобождена правильно.
Зачем??????
Заранее спасибо
Fabio