我不想创建 NSTimer 对象。如何使计时器无效?我想使 viewWillDisappear 中的计时器无效。
-(void) viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}
一种
你必须坚持你创建的计时器:
@interface MONObject ()
@property (nonatomic, retain) NSTimer * timerIvar;
@end
@implementation MONObject
...
- (void)viewDidLoad
{
[super viewDidLoad];
self.timerIvar = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}
- (void)invalidateTimer
{
[self.timerIvar invalidate];
self.timerIvar = nil;
}
- (void)viewWillDisappear:(BOOL)animated
{
...
[self invalidateTimer];
}
乙
另一种选择是使回调中传递的计时器无效,但这不会发生在viewDidUnload:
. 因此,它并不完全适用于这种情况:
- (void)onTimer:(NSTimer *)pTimer
{
[pTimer invalidate];
}
如果您希望能够取消计时器,则必须参考要取消的计时器,这意味着您必须保留指向计时器的指针,请参阅贾斯汀的回答。
保持对计时器的引用是正确的方法,但为了完整起见,您也可以将该-performSelector:withObject:afterDelay:
方法用作穷人的计时器。该调用可能会使用+cancelPreviousPerformRequestsWithTarget:
. 示例代码:
- (void) viewDidLoad
{
[super viewDidLoad];
[self performSelector:@selector(timerTick) withObject:nil afterDelay:10];
}
进而:
- (void) viewWillDisappear
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[super viewWillDisappear];
}
但这不是正确的方法,因为您可能会取消您的对象上未决的其他执行选择器请求。最好保留计时器,这样您就可以确切地知道要取消的内容。
顺便说一句,在-viewDidLoad
. 视图加载可能随时发生,与显示的视图无关。
也许这种方法可以帮助你:
[self performSelector:@selector(onTimer:) withObject:nil afterDelay:10];
如果您不想保留计时器,则 NSTimer 对象将被传递给计时器方法(在您的情况下为 onTimer:),因此在该方法中您可以检查是否仍然需要计时器并将其无效。但是,如果视图在您使计时器无效之前返回并创建一个新的,您将遇到麻烦。
到目前为止,最好的方法是将计时器存储到实例变量中。它有效,没有聪明的技巧,六个月后你就会知道你做了什么。我可能会写一个
@property (readwrite, nonatomic) BOOL hasTimer;
如果计时器不为零,getter 返回 YES,setter 使计时器无效或创建一个新计时器。