То, как вы делаете это, вы никогда не ударил dealloc
. Таймер сохраняет свою цель. В этом случае это означает, что таймер сохранил вас. Он не освободит вас, пока не будет признан недействительным. Поскольку вы создали таймер, вы также должны аннулировать его в какой-то момент до dealloc
, поскольку сохранение таймера будет препятствовать тому, чтобы ваш объект был dealloc
ed.
У вас есть два варианта:
- найти другое место, чтобы аннулирует таймер (вид идет закадровым, приложение завершает, что ты)
- набора что-то еще в качестве цели таймера.
В качестве примера последнего:
@interface GameLoopTimerTarget : NSObject {
id owner; /* not retained! */
}
- (id)initWithOwner:(id)owner;
- (void)timerDidFire:(NSTimer *)t;
@end
@implementation GameLoopTimerTarget
- (id)initWithOwner:(id)owner_ {
self = [super init];
if (!self) return nil;
owner = owner_;
return self;
}
- (void)timerDidFire:(NSTimer *)t {
#pragma unused (t)
[owner performSelector:@selector(gameLoop)];
}
@end
/* In your main object… */
/* assume synthesized:
@property (retain, NS_NONATOMIC_IPHONE_ONLY) GameLoopTimer *mainTimerTarget; */
- (void)mainTimerLoop {
self.mainTimerTarget = [[[GameLoopTimerTarget alloc] initWithOwner:self] autorelease];
mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0 target:self.mainTimerTarget selector:@selector(timerDidFire:) userInfo:nil repeats:YES];
}
- (void)dealloc {
/* other stuff */
[timer invalidate], timer = nil;
[mainTimerTarget release], mainTimerTarget = nil;
/* more stuff */
[super dealloc];
}
Обратите внимание, как интервал времени является 1.0/10.0
- это также может быть написана 0.1
, но не может быть написано 1/10
, поскольку это подразделение будет укоротить до 0.0
.
заметить также, как это нарушает цикл сохранения:
- И вы, и таймер удержания цели таймера.
- Вы удаляете dealloc в обычное время.
- Затем вы аннулируете таймер и отпускаете цель таймера.
- Точка таймера затем освобождается.
Это неправильно - и это очень плохой совет! Управление памятью с помощью NSTimer очень своеобразно: он сохраняет цель и не освобождает ее до тех пор, пока она не будет признана недействительной. Если он создает повторяющийся NSTimer с самим собой в качестве цели, поэтому таймер сохраняет себя, и поэтому dealloc не будет вызываться до * после * таймер недействителен. Поэтому не говорите «остановите таймер» в * вашем методе dealloc ». Хитрость заключается в том, чтобы найти место для остановки таймера * до * метода dealloc. – matt
Проголосовали по тем же причинам, что и матовый. Необходимо отключить и отпустить таймер за пределами dealloc. – theLastNightTrain