如何停止 NSTimer

Posted

技术标签:

【中文标题】如何停止 NSTimer【英文标题】:How to stop NSTimer 【发布时间】:2011-03-31 08:32:49 【问题描述】:

嘿,我只是在制作一个示例应用程序,但遇到了一些麻烦,所以我有一个表格视图,然后我有几行,当用户单击一行时,它会将他们带到一个新视图。在这个视图中,我有一个播放音乐的按钮。我正在使用计时器根据音乐持续时间和剩余时间增加滑块。

现在我的问题是,当我通过左上角按钮返回表格视图时,我必须放置什么,这样 NSTimer 才会停止?

这是我目前所拥有的,我无法重复:YES timer to stop。

#import "SecondViewController.h"

@implementation SecondViewController
@synthesize lbl1;
@synthesize timer;

-(IBAction) slide 
 myMusic.currentTime = slider.value;


-(IBAction)play

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
 slider.maximumValue = [myMusic duration];
 myMusic.volume = 0.2;
 [myMusic prepareToPlay];
 [myMusic play];


-(IBAction)pause

 [myMusic pause];


-(IBAction)stop

 slider.value = 0;
 myMusic.currentTime = 0;
 [myMusic stop];


- (void)updateTime
  slider.value = myMusic.currentTime;


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 

  //This plays music, we must give it a path to find the file and then u can change it. 
 NSString * pathToMusicFile = [[NSBundle mainBundle] pathForResource:@"Katy" ofType:@"mp3"];
     myMusic = [[ AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile] error:NULL];
     myMusic.delegate = self;
     myMusic.numberOfLoops = -1;

 slider.value = 0;
 //[myMusic play];

    [super viewDidLoad];



- (void)viewDidUnload 

 [timer invalidate];
 timer = nil;
 //myMusic.currentTime = 0;
 [myMusic stop];
 [super viewDidUnload];

 // Release any retained subviews of the main view.
 // e.g. self.myOutlet = nil;


-(IBAction) TxtChange;

 lbl1.text = @" test2! I CHNAGED TEXT FROM ANOTHER XIB";


- (void)dealloc 
 [timer invalidate];
 timer = nil; 
 [myMusic release];
    [super dealloc];


@end

【问题讨论】:

【参考方案1】:

只是让定时器失效

[定时器失效];

【讨论】:

【参考方案2】:

使用下面的代码。它会工作 但请记住,只有在我们的计时器处于运行模式时才能调用它,否则应用程序将崩溃。

- (void)viewWillDisappear:(BOOL)animated 
    //BEFORE DOING SO CHECK THAT TIMER MUST NOT BE ALREADY INVALIDATED
    //Always nil your timer after invalidating so that 
    //it does not cause crash due to duplicate invalidate
       if(timer)
       
         [timer invalidate];
         timer = nil;
       
    [super viewWillDisappear:animated];

【讨论】:

我打算在早上 2 点去试试这个,整天都卡在这个上了。希望您的解决方案有效。我会在几个小时后回到这篇文章。 有人应该告诉他,他迟到了大约 3 年才回复你的事情……不管怎样,解决了我的问题! 所以@cruisx,你的问题解决了吗? 在 viewWillDisappear 中停止计时器时要非常小心。如果您的应用程序进入后台,则不会调用此方法。在这种情况下,您可能希望停止计时器,以避免操作系统杀死您的应用。【参考方案3】:

4 岁的帖子,我知道,但也许我可以让 NEXT 人免于浪费时间尝试使 NSTimer 无效。苹果的文档解释了它,它对我有用。

在.h中

@property(nonatomic, retain) NSTimer *yourTimer;
@property(weak) NSTimer *repeatingTimer;

在.m

@synthesize yourTimer, repeatingTimer;

在 viewDidLoad 中

yourTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimerInterval)(40.0/60.0)
                                             target:self
                                           selector:@selector(blink)
                                           userInfo:nil
                                            repeats:TRUE];

  self.repeatingTimer = yourTimer;

在我看来DidDisappear

   [repeatingTimer invalidate];
   repeatingTimer = nil;

诀窍在于将第一个 NSTimer 分配给(弱)NStimer 对象并杀死该对象。

【讨论】:

【参考方案4】:

你可以使用两种不同的东西

    [timername invalidate];

或者你可以使用

    timername = nil;

【讨论】:

后一个实际上不会停止计时器,第一个已经在 2010 年 8 月发布。【参考方案5】:

技巧是使用单例类, google myGlobals 类,主要用作单例 虽然如果你确实想使用NSTimer,那么

假设视图 1 是您进入的视图,视图 2 是您返回的视图 2。

因此,在视图 2 的情况下,编写 NSTimer 以使 viewDidLoad 中的计时器无效(假设两个视图都有两个单独的类)。会出现问题,因为当您转到视图 1 时,视图 2计时器将被释放。因此,创建一个 Singleton 类并像这样保存 NSTimer 指针

//to be done in viewDidLoad function
theGlobals *globals = [theGlobals alloc] init];// for the singleton class to initiate,
[globals.myTimer invalidate];


//to be done in viewDidUnload
theGlobals *globals = [theGlobals alloc] init];// for the singleton class to initiate,
globals.myTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0
                                                 target: self
                                               selector:@selector(onTick)
                                               userInfo: nil repeats:YES];

哦,这是你需要的 myGlobals 类代码

//theglobals.h file

#import <Foundation/Foundation.h>


@interface theGlobals : NSObject 

    NSTimer *myTimer;


@property (nonatomic, copy) NSString *changeyes;



+(theGlobals*)sharedInstance;
@end

//implementaton .m file

#import "theGlobals.h"
@implementation theGlobals

@synthesize myTimer;



static theGlobals *sharedInstance;

- (id) init

return self;


+(theGlobals*)sharedInstance

if (!sharedInstance)

    sharedInstance = [[theGlobals alloc] init];

return sharedInstance;

@end

【讨论】:

【参考方案6】:

正如 iCoder 所说,它必须在 viewWillDisappear 中失效。

我添加以下内容只是为了确保。这个对我有用。希望它有所帮助(并添加到 icors 的答案不打算复制)

- (void) startTimer

[self stopTimer];
timer = [NSTimer scheduledTimerWithTimeInterval: 5.0
                                                     target: self
                                                   selector:@selector(onTick)
                                                   userInfo: nil repeats:YES];



- (void) stopTimer

    if (timer) 
        [timer invalidate];
        timer = nil;
    


【讨论】:

【参考方案7】:

像这样:

[yourtimername invalidate];

但请注意,如果计时器已经停止,则无法停止计时器,因为您的应用会崩溃。

【讨论】:

当我使未实例化的计时器无效时,应用程序不会崩溃。

以上是关于如何停止 NSTimer的主要内容,如果未能解决你的问题,请参考以下文章

iOS NSTimer定时器

如何正确停止线程

ORACLE如何停止一个JOB

Tomcat停止时如何停止执行线程?

Android如何停止线程的方式

如何将VBS停止