无效时NSTimer不会停止

时间:2013-05-10 05:21:45

标签: objective-c nstimer

我的.h文件中有以下代码:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <AVFoundation/AVFoundation.h>
#import <MapKit/MapKit.h>

@interface LandingController : UIViewController<CLLocationManagerDelegate> {
    CLLocationManager *LocationManager;
    AVAudioPlayer *audioPlayer;

}

@property (nonatomic, retain) NSTimer *messageTimer;

- (IBAction)LoginButton:(id)sender;

@end

我的.m文件中有以下代码:

@interface LandingController ()

@end

@implementation LandingController
@synthesize messageTimer;

- (void)checkForMessages
{

    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"BINGO:"
                          message:@"Bingo This Works"
                          delegate:nil
                          cancelButtonTitle:@"Okay"
                          otherButtonTitles:nil];

    [alert show];

}

- (IBAction)LoginButton:(id)sender {

    if ([UserType isEqualToString:@"Owner"]) {

        if (messageTimer){ 
        [self.messageTimer invalidate];
        self.messageTimer = nil;
        }

    } else {

        if (!messageTimer){

           self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                             target:self
                                    selector:@selector(checkForMessages)
                                                           userInfo:nil
                                                            repeats:YES];


        }
    }

}

@end

但是当我调用无效时,我的计时器不想停止。

LoginButton只被按下两次,一次当strResult = =“Guard”时,然后应用程序将其更改为等于“Owner”并且用户再次按下登录按钮,所以我不认为我设置多个计时器。

按下登录按钮并启动计时器后,我转到另一个视图然后再次按下再次按下登录按钮,这是我希望计时器停止的时间。我是否需要做一些特别的事情来获取messageTimer,因为我将视图切换了片刻然后又回来了?

有什么想法吗?

谢谢!

7 个答案:

答案 0 :(得分:32)

您需要在创建计时器的同一个线程上调用[self.messageTimer invalidate]。只需确保在主线程上创建并使计时器无效。

dispatch_async(dispatch_get_main_queue(), ^{
    if ([UserType isEqualToString:@"Owner"]) {
        [self.messageTimer invalidate];
        self.messageTimer = nil;
    } else {
        self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                             target:self
                                                           selector:@selector(checkForMessages)
                                                           userInfo:nil
                                                            repeats:YES];
    }
});

答案 1 :(得分:14)

NSTimer由NSRunLoop保留,因此我发现问题的唯一方法是,如果您实际创建了多个计时器并且仅使您所引用的内容无效。

示例:

if(!timer)
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:(self) selector:@selector(processTimer) userInfo:nil repeats:YES];

答案 2 :(得分:3)

您是否尝试将重复列为否

self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                             target:self
                                                          selector:@selector(checkForMessages)
                                                           userInfo:nil
                                                            repeats:NO];

答案 3 :(得分:2)

如果最后的代码(以if开头)使用UserType!= Owner调用两次,则创建一个新的计时器而不会使旧的计时器失效。现在有两个计时器在运行。如果代码第三次执行,您将添加第三个计时器,依此类推。使用UserType == Owner执行代码只会使最后一个计时器失效,即使它被重复调用,它也不会使较旧的计时器失效。

你有计时器泄漏。 ; - )

答案 4 :(得分:1)

如何在NSLog方法中添加checkForMessages?检查是否真的只有1个计时器会更容易。

(我宁愿把它放在评论中,但我没有那么多的声誉......)

答案 5 :(得分:0)

我有一种停止或停用计时器的方法,在应用之前请确保您已经尝试了上述所有情况,这样您也可以理解为什么这种方法最终会被使用。

 // Instead of self use NSTimer class, it will not provide you any crash and in selector placed any empty function and setRepeats to NO

self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:100.0
                       target:NSTimer selector:@selector(emptyFunctionCalling)
                                                                   userInfo:nil
                                                                    repeats:NO];
[self.messageTimer invalidate];
 self.messageTimer = nil;

因此,只要发生计时器不会停止,然后输入此代码,计时器将永久停止。

答案 6 :(得分:0)

它奇怪但使传递的计时器参考无效并创建了计时器参考对我有用。

    delayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateDelayLable:) userInfo:nil repeats:YES];

    -(void)updateSendDataDelayLable:(NSTimer*)timer{
delayValueForGNSS--;

                if (delayValueForGNSSSend==0) {
                     [timer invalidate];
                     timer = nil;
                     [delayTimer invalidate];
                     delayTimer = nil;
                }
            }