【问题标题】:NSTimer Does not Stop with Navigation ControllerNSTimer 不会随着导航控制器停止
【发布时间】:2015-03-23 11:43:51
【问题描述】:

我是 iOS 新手, 在我的项目中,我将 NSTimer 与导航控制器一起使用。 我在我的项目中使用了两个类, 第 1 类是 ViewController,第 2 类是 PlayTheme。 ViewController 和 PlayTheme 类与 segue 相连。 在 PlayTheme 类中,我使用 NSTimer 和“FiredTimer 方法”调用每 10 毫秒。 PlayTheme类的源代码是: 下面是 NSTimer 启动的方法

- (IBAction)startTimerMethod:(id)sender
{
    UIBackgroundTaskIdentifier bgTask =0;
        UIApplication  *app = [UIApplication sharedApplication];
        bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
            [app endBackgroundTask:bgTask];
        }];

    timer = [NSTimer
             scheduledTimerWithTimeInterval:0.01
             target:self
             selector:@selector(timerFired:)
             userInfo:nil
             repeats:YES];
}

下面的方法是停止计时器

- (IBAction)stopTimerMethod:(id)sender
{
    if([timer isValid])
    {
        [timer invalidate];
        timer=Nil;
    }
}

两种方法都有效,但是当我按照以下步骤操作时,计时器不会停止:

  1. 我在 PlayTheme 类和 StartTime 中
  2. 返回 ViewController
  3. 回到 PlayTheme 课程
  4. 和StopTimer方法调用,方法调用但不停止定时器

给我建议以解决我的问题,并告诉我 NSTimer 如何在 BackGround 中使用 NSTimer 播放特定时间的声音?

谢谢你。

【问题讨论】:

    标签: ios objective-c nstimer avaudioplayer navigationcontroller


    【解决方案1】:

    有几种解决方案可以解决您的问题:

    • 不鼓励 - 要么在全局范围内存储对 NSTimer 实例的引用(查看 Singleton 设计模式)
    • 推荐 - 从第一个视图控制器实例化您的计时器,以便您始终保持对它的引用,并最终将其传递给您的目标 PlayTheme 视图控制器。

    请始终牢记,如果您必须与多个实例共享一个元素,则该元素必须由所有这些实例的第一个共同父亲管理。

     VC1 -> VC2 -> VC3
     VC1 -> VC5
     // In such a case, if both VC3 and VC5 need to share an element,
     // this one must be managed by VC1
    

    【讨论】:

      【解决方案2】:

      你能告诉我你是如何添加计时器的吗?

      应该是这样的-

      [[NSRunLoop mainRunLoop] addTimer: timer forMode:NSRunLoopCommonModes];

      【讨论】:

        【解决方案3】:

        创建一个后台定时器子类 NSOperation 并创建它的实例。此外,要让计时器在特定持续时间内保持活动状态,您需要指定当前时间 + 持续时间的日期,如下所示 -

        #import <Foundation/Foundation.h>
        
        @interface BackgroundTimer : NSOperation
        {
            BOOL _done;
        }
        @end
        
        
        
        #import "BackgroundTimer.h"
        
        @implementation BackgroundTimer
        
        -(void) main
        {
            if ([self isCancelled])
            {
                return;
            }
        
            NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30
                                                     target:self
                                                   selector:@selector(timerFired)
                                                   userInfo:nil
                                                    repeats:YES];
        
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        
            //keep the runloop going as long as needed
            while (!_done && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                                      beforeDate:[NSDate dateTillTheSpecificTime]]);
        

        }

        @结束

        【讨论】:

          【解决方案4】:

          当您退出 PlayTheme 视图控制器时,您会丢失对计时器的引用。如果要保留对计时器的引用,则需要将计时器“全局”存储在某个地方。执行此操作的方式和位置取决于应用程序的结构。

          编辑

          澄清:我不建议使用全局变量!我只是写了这个来表示一个变量“存在”在更多的地方,而不是一个控制器。检查@sweepy_ 的答案以获得可能的解决方案。

          【讨论】:

            猜你喜欢
            • 2010-11-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-02-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多