UIView подкласс не освобождается
У меня есть подкласс UIView, который не освобождается. Я знаю, что только один класс создает экземпляр моего представления. У меня есть NSTimer ivar на мой взгляд. Если я закомментирую этот таймер и при касании кнопки отмены, которая находится на этом контроллере представления, вызывается Deloc в этом представлении. Если я не закомментирую таймер, dealloc никогда не будет вызван.
//CustomUIView
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_pollTimer = [[NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES] retain];
}
}
Я хочу сохранить ссылку на этот таймер, потому что есть моменты, когда я хочу приостановить таймер. Теперь у меня может быть свойство для моего представления для таймера, и в методе dealloc класса, который имеет ссылку на мой пользовательский интерфейс, я могу сделать его недействительным перед выпуском указанного представления. Мне не очень нравится этот подход, потому что я не хочу показывать этот таймер внешним объектам.
У кого-нибудь есть идеи?
3 ответа
NSTimer
всегда сохраняет свою цель. Это имеет два значения:
Вы не должны иметь представление (которое является целью таймера), чтобы сохранить таймер, так как это создаст цикл.
Ваш вид никогда не будет отменен, пока таймер остается активным.
Вместо этого вы должны позвонить invalidate
на таймере всякий раз, когда ваше мнение сделано с ним. Как только это будет сделано, вид будет dealloc
когда счетчик ссылок становится равным нулю.
Обычно это происходит, когда представление удаляется из его суперпредставления; если вы хотите, чтобы он продолжал использовать свой таймер до тех пор, пока это не произойдет, а затем освободиться, вы можете переопределить removeFromSuperview
сделать недействительным таймер и затем вызвать super
,
Вы не должны сохранять таймер. Расписание таймера, как это: _pollTimer = [NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES];
и всякий раз, когда вы хотите сделать его недействительным: [_pollTimer invalidate]
Редактировать:
В вашем -dealloc
метод, попробуйте это:
- (void) dealloc
{
[_pollTimer invalidate];
/*
If not using ARC:
[_pollTimer release], _pollTimer = nil;
[super dealloc];
*/
}
Вы забыли позвонить super
Реализация -initWithFrame:
! Упс!
- (id) initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
_pollTimer = [[NSTimer scheduleTimerWithTimeInterval:0.2 target:self selector:@selector(onPollTimerFired:) userInfo:nil repeats:YES] retain];
}
return self;
}
Это должно работать намного лучше.