【问题标题】:trouble invalidating an NSTimer using arc - IOS使用 arc 使 NSTimer 无效的麻烦 - IOS
【发布时间】:2013-03-20 23:04:09
【问题描述】:

这个问题已经在堆栈溢出时被问死了,我已经看到了很多答案,但不知何故我仍然遇到了麻烦。

无论如何,我分配了一个 NSTimer,因为在我看来确实加载了:

NSTimer *oneSecondTicker = [[NSTimer alloc] init]; 
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES]; 
self.dateForTimeLabel = [NSDate date];

选择器的方法是:

-(void) updateLabelsWithOneSecondTicker {
    if(self.dateForTimeLabel != nil)  
    {
        self.lblTime.text = [NSString stringWithFormat:@"%f", fabs([self.dateForTimeLabel timeIntervalSinceNow])];
    }
}

这种方法基本上每秒更新一个标签,给我一个计时器/秒表之类的东西。

我还有一个开始/暂停按钮,当按下它来暂停时:

[oneSecondTicker invalidate];
oneSecondTicker = nil;

如果按下按钮再次启动,方法是:

NSTimer *oneSecondTicker = [[NSTimer alloc] init];
oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];    

self.dateForTimeLabel = [NSDate date];

我没有给定时器调用retain,它没有属性,也没有被合成。然而,它在接口中被声明。

为了解决这个问题,每次按下暂停/开始按钮都会发生什么,计时器不会失效,并且时间标签会越来越快地更新,这让我相信出于某种原因存在多个计时器。 (显然,在这些方法中还没有真正的计时器功能,这只是让我的 NSTimer 工作的测试)。

这怎么可能?

【问题讨论】:

    标签: ios nstimer


    【解决方案1】:

    这是你写的:

    NSTimer *oneSecondTicker = [[NSTimer alloc] init];
    

    该行创建了一个 local 变量。它确实不设置您在界面中声明的属性。该行还创建了一个计时器,当您重新分配oneSecondTicker 以指向您使用scheduledTimerWithTimeInterval: 创建的计时器时,您会立即在下一行中将其销毁。这是一个初学者的错误,表明您需要了解指针的工作原理。

    无论如何,您正在使用scheduledTimerWithTimeInterval:... 创建计时器。这意味着计时器在运行循环中自动调度自身。当一个定时器被安排在一个运行循环中时,运行循环会保留这个定时器。这就是为什么(假设您使用 ARC)即使您释放对它的引用,计时器仍然存在。

    您需要将计时器存储在您的实例变量中。我假设您使用的是 Xcode 4.4 或更高版本,因此该属性正在自动合成。如果你声明了@property (nonatomic, strong) NSTimer *oneSecondTicker这样的属性,那么你可以像这样创建计时器:

    self.oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES]; 
    

    当你想使它失效时,你可以这样说:

    [self.oneSecondTicker invalidate];
    self.oneSecondTicker = nil;
    

    【讨论】:

      【解决方案2】:

      您没有保留计时器变量。

      删除这个:

      NSTimer *oneSecondTicker = [[NSTimer alloc] init]; 
      

      将你的计时器移动到类属性为@property (strong)NSTimer *oneSecondTicker;

      使用这个:

      self.oneSecondTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateLabelsWithOneSecondTicker) userInfo:nil repeats:YES];
      

      重新启动计时器时再次使用 self.oneSecondTicker。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-04
        • 1970-01-01
        • 2020-05-06
        • 2021-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        相关资源
        最近更新 更多