Задержка освобождения ивара после того, как родительский объект был освобожден - PullRequest
1 голос
/ 21 октября 2011

У меня есть класс TouchInfo, который имеет ивар класса MotionStreak.

@interface TouchInfo : NSObject {
    MotionStreak *streak;
}
...
@end

Этот класс в основном обрабатывает событие касания и рисует полосу движения, которая следует за касанием.Я хочу выпустить экземпляр TouchInfo, который ассоциируется с определенным касанием, когда пользователь отпускает палец, но я хочу, чтобы полоса движения сохранялась от 0,5 до 1,0 секунды до исчезновения, поэтому я не могу выпустить streakivar в методе dealloc класса TouchInfo.

Я использую таймер для задержки выпуска streak ivar, используя собственный класс таймера следующим образом:

- (void)dealloc {
    [self timedReleaseStreak];
    [super dealloc];
}

- (void)timedReleaseStreak {
    [streak fadeoutWithDelay:1.0];
    [[TimerHandler sharedTimer] object:streak action:@selector(release) delay:1.0];
}

Пока все работает без сбоев.Но мне интересно, если я делаю это неправильно, и есть ли лучший и рекомендуемый способ сделать это.Пожалуйста, совет.

p / s: Пожалуйста, никаких советов по ARC;Я еще не выполнил автоматический выпуск мастера подсчета ссылок: P

1 Ответ

0 голосов
/ 21 октября 2011

Поскольку блоки сохраняют любые объекты, на которые они ссылаются при копировании, вы можете реализовать анимацию, используя их, что предотвратит освобождение объекта до тех пор, пока блок не будет освобожден.

Вот пример, который использует +[UIView animateWithDuration:animations:completion:], чтобы скрыть вид и удалить его из иерархии видов. Чтобы использовать блок завершения позже, он должен скопировать его в кучу, что приведет к сохранению представления.

- (void)dealloc {
    UIView *localStreak = streak;
    [UIView animateWithDuration:1.0 animations:^ {
        localStreak.alpha = 0.0;
    } completion:^ (BOOL finished) {
        [localStreak removeFromSuperview];
    }];
    [streak release];
    [super dealloc];
}

Обратите внимание, что я скопировал streak ivar в локальную переменную и использовал его в блоке. Если вы попытаетесь использовать ivar напрямую, он сохранит self, что не сработает, потому что вы уже запускаете процесс освобождения.

...