如何停止 NSTimer

发布于 2024-09-15 04:50:11 字数 1788 浏览 1 评论 0原文

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

现在我的问题是,我必须输入什么,以便当我通过左上角按钮返回表视图时,NSTimer 停止?

这就是我到目前为止所拥有的,我无法得到重复:是的计时器停止。

#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

Hey so i am just making an example application and i am having a little trouble, So i have a table view and then i have a few rows and when a user clicks a row it takes them to a new view. On this view i have a button to play music. I am using a timer to make a slider bar increase based on music duration and remaining time.

Now my problem is, what do i have to put so that when i go back to the table view via the top left button, that the NSTimer stops?

this is what i have so far, i cannot get a repeat: 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

内心荒芜 2024-09-22 04:50:12

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

    [timername invalidate];

或者你可以使用

    timername = nil;

You Could Use Two Different Things

    [timername invalidate];

Or You Could Use

    timername = nil;
孤独岁月 2024-09-22 04:50:12

技巧是使用单例类,
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

Trick is to use a singleton class,
google myGlobals class which is mostly used as a singleton
Although if u do wish to use NSTimer, then

lets say the view 1 is which u go into and view 2 is the one which u go back 2.

So in case of view 2, write the NSTimer to invalidate the timer in the viewDidLoad(Assuming you have two separate classes for both views).Problem will occur because when u go to view 1, the view 2 Timers will be dealloc. So, make a Singleton class and save the NSTimer pointer like this

//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];

oh , and here is the myGlobals class code that u will need

//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
仙气飘飘 2024-09-22 04:50:12

只是使定时器无效

[timer invalidate];

Just invalidate the timer

[timer invalidate];

深府石板幽径 2024-09-22 04:50:11

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

- (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];
}

Use the below code. It will work
But keep in mind that it must only be called if our timer is in running mode else the application will get crashed.

- (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];
}
浊酒尽余欢 2024-09-22 04:50:11

像这样:

[yourtimername invalidate];

但要小心,如果计时器已经停止,则无法停止计时器,因为您的应用程序会崩溃。

like this:

[yourtimername invalidate];

But be careful, you cant stop the timer if it's already stopped because your app will crash.

鹤舞 2024-09-22 04:50:11

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

我添加以下内容只是为了确定。它对我有用。希望它有帮助(并添加到 icoders 答案中,无意复制)

- (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;
    }

}

As iCoder says it has to be invalidated in viewWillDisappear.

I added the following just to make sure. it works for me. Hope it helps (and adds to icoders answer do not intent to copy)

- (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;
    }

}
星光不落少年眉 2024-09-22 04:50:11

4 年前的帖子,我知道,但也许我可以让下一个家伙免于浪费时间尝试使 NSTimer 失效。苹果文档解释了这一点,它对我有用。

.h 中

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

@synthesize yourTimer, repeatingTimer;

中的 viewDidLoad 中

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

  self.repeatingTimer = yourTimer;

在我的 viewDidDisappear

   [repeatingTimer invalidate];
   repeatingTimer = nil;

,技巧在于将第一个 NSTimer 分配给(弱) NSTimer 对象并杀死该对象。

4 year old post, I know but maybe I can save the NEXT guy from wasting time trying invalidate a NSTimer. Apples documentation explains it and it works for me.

in .h

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

in .m

@synthesize yourTimer, repeatingTimer;

in viewDidLoad

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

  self.repeatingTimer = yourTimer;

in my viewDidDisappear

   [repeatingTimer invalidate];
   repeatingTimer = nil;

the trick is in the assignment of the first NSTimer to (weak) NStimer object and killing THAT object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文