rde*_*fin 0 cocoa-touch objective-c nstimer ios
我有以下代码来创建一个NSTimer应该在每次触发时更新标签的代码:
.h文件
@interface Game : UIViewController
{
NSTimer *updateTimer;
UILabel *testLabel;
int i;
}
-(void)GameUpdate;
@end
Run Code Online (Sandbox Code Playgroud)
.m文件
@implementation Game
-(void)GameUpdate
{
i++;
NSString *textToDisplay = [[NSString alloc] initWithFormat:@"Frame: %d", i];
[testLabel setText:textToDisplay];
NSLog(@"Game Updated");
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01428 target:self selector:@selector(GameUpdate) userInfo:nil repeats:YES];
}
//other methods (viewDidUnload, init method, etc.)
@end
Run Code Online (Sandbox Code Playgroud)
当我运行它时,顶部会出现一个标签,显示"0"但不会改变.它让我相信我错过了如何NSTimer设置.我错过了什么?
我使用断点和(如您所见)记录以查看方法是否实际运行,而不是其他一些错误.
Sco*_*len 14
我遇到了类似的问题,它有一个与运行循环相关的不同根本原因.值得注意的是,当您使用代码安排Timer时:
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01428 target:self selector:@selector(GameUpdate) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)
计时器将使用当前线程的runLoop进行调度.在你的情况下,因为你在viewDidLoad中进行了这个调用,它是主线程,所以你很高兴.
但是,如果使用主线程以外的线程安排计时器,它将在该线程的runLoop上进行调度,而不是主线程.这很好,但是在辅助线程上,你负责创建和启动初始运行循环,所以如果你还没有这样做 - 你的回调永远不会被调用.
解决方案是为您的辅助线程启动runLoop,或者将您的计时器启动分配给主线程.
派遣:
dispatch_async(dispatch_get_main_queue(), ^{
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01428 target:self selector:@selector(GameUpdate) userInfo:nil repeats:YES];
});
Run Code Online (Sandbox Code Playgroud)
要启动runloop:
使用您选择的API创建线程后,调用CFRunLoopGetCurrent()为该线程分配初始运行循环.将来对CFRunLoopGetCurrent的任何调用都将返回相同的运行循环.
CFRunLoopGetCurrent();
updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01428 target:self selector:@selector(GameUpdate) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)
你的回调必须有这个签名:
-(void)GameUpdate:(NSTimer *)timer
Run Code Online (Sandbox Code Playgroud)
这在文档中明确说明.设置计时器时的@selector()引用应该是@selector(GameUpdate:)(注意尾随:).
试试吧.
| 归档时间: |
|
| 查看次数: |
3214 次 |
| 最近记录: |