8

我的 .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 ,因为我切换了一会儿视图然后又回来了?

有任何想法吗?

谢谢!

4

7 回答 7

35

您需要调用[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];
    }
});
于 2013-05-10T08:16:35.947 回答
17

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

例子:

if(!timer)
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:(self) selector:@selector(processTimer) userInfo:nil repeats:YES];
于 2013-05-10T05:31:08.667 回答
3

您是否尝试将重复设置为否

self.messageTimer = [NSTimer scheduledTimerWithTimeInterval:10.0
                                                             target:self
                                                          selector:@selector(checkForMessages)
                                                           userInfo:nil
                                                            repeats:NO];
于 2013-05-10T05:40:54.360 回答
2

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

你有一个计时器泄漏。;-)

于 2013-05-10T08:04:54.277 回答
1

NSLog在你的checkForMessages方法中加入一个怎么样?检查是否真的只有1个计时器会更容易。

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

于 2013-05-10T07:58:02.817 回答
1

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

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

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

于 2016-10-14T05:02:09.977 回答
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;
                }
            }
于 2019-07-08T21:20:25.753 回答