NSTimer 不会随着导航控制器停止
NSTimer Does not Stop with Navigation Controller
我是 iOS 的新人,
在我的项目中,我将 NSTimer 与导航控制器一起使用。
我在我的项目中使用了两个 Classes,
Class 1 是 ViewController,第二个 Class 是 PlayTheme。
ViewController 和 PlayTheme Classes 与 segue 相连。
在 PlayTheme Class 中,我使用了 NSTimer 并且 "FiredTimer method" 每 10 毫秒调用一次。
PlayTheme Class 的源代码是:
下面的 NSTimer Start 方法
- (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;
}
}
两种方法都有效,但是当我按照以下步骤操作时,计时器不会停止:
- 我在 PlayTheme Class 和 StartTime
- 返回 ViewController
- 回来玩主题Class
- 和StopTimer方法调用,方法调用但不停止定时器
给我解决问题的建议,并告诉我 NSTimer 如何在后台工作以使用 NSTimer 在特定时间播放声音?
感谢您的进阶。
当您退出 PlayTheme 视图控制器时,您将失去对计时器的引用。如果您想保留对计时器的引用,则需要将计时器存储在某个地方 'globally'。执行此操作的方式和位置取决于应用程序的结构。
编辑
澄清一下:我不建议使用全局变量!我只是写那个来指示一个变量 'exists' 在更多地方然后只是一个控制器。查看@sweepy_ 的回答以获得可能的解决方案。
请问您是如何添加定时器的?
应该是这样的-
[[NSRunLoop mainRunLoop] addTimer: 计时器 forMode:NSRunLoopCommonModes];
有几种解决方案可以解决您的问题:
- 不鼓励 - 全局存储对 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
创建一个后台计时器子类 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]]);
}
@end
我是 iOS 的新人, 在我的项目中,我将 NSTimer 与导航控制器一起使用。 我在我的项目中使用了两个 Classes, Class 1 是 ViewController,第二个 Class 是 PlayTheme。 ViewController 和 PlayTheme Classes 与 segue 相连。 在 PlayTheme Class 中,我使用了 NSTimer 并且 "FiredTimer method" 每 10 毫秒调用一次。 PlayTheme Class 的源代码是: 下面的 NSTimer Start 方法
- (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;
}
}
两种方法都有效,但是当我按照以下步骤操作时,计时器不会停止:
- 我在 PlayTheme Class 和 StartTime
- 返回 ViewController
- 回来玩主题Class
- 和StopTimer方法调用,方法调用但不停止定时器
给我解决问题的建议,并告诉我 NSTimer 如何在后台工作以使用 NSTimer 在特定时间播放声音?
感谢您的进阶。
当您退出 PlayTheme 视图控制器时,您将失去对计时器的引用。如果您想保留对计时器的引用,则需要将计时器存储在某个地方 'globally'。执行此操作的方式和位置取决于应用程序的结构。
编辑
澄清一下:我不建议使用全局变量!我只是写那个来指示一个变量 'exists' 在更多地方然后只是一个控制器。查看@sweepy_ 的回答以获得可能的解决方案。
请问您是如何添加定时器的?
应该是这样的-
[[NSRunLoop mainRunLoop] addTimer: 计时器 forMode:NSRunLoopCommonModes];
有几种解决方案可以解决您的问题:
- 不鼓励 - 全局存储对 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
创建一个后台计时器子类 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]]);
}
@end