#objective-c #memory-management #ivar
#objective-c #управление памятью #ivar
Вопрос:
У меня есть класс TouchInfo, который имеет ivar класса MotionStreak .
@interface TouchInfo : NSObject {
MotionStreak *streak;
}
...
@end
Этот класс в основном обрабатывает событие касания и рисует полосу движения, которая следует за касанием. Я хочу освободить экземпляр TouchInfo
, который связан с определенным касанием, когда пользователь отпускает свой палец, но я хочу, чтобы полоса движения оставалась от 0,5 до 1,0 секунды, прежде чем исчезнуть, поэтому я не могу освободить streak
ivar в dealloc
методе TouchInfo
class .
Я использую таймер для задержки выпуска 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. Я бы подумал, что передача ответственности другому объекту (затронутому представлению), возможно, была бы безопаснее?
Ответ №1:
Поскольку блоки сохраняют любые объекты, на которые они ссылаются при копировании, вы можете реализовать свою анимацию, используя их, что предотвратит освобождение объекта до освобождения блока.
Вот пример, который используется [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
, что не сработает, потому что вы уже запускаете процесс освобождения.