NSTimer 和更新 UI
我一直在尝试让我的游戏在 NSTimer
上正常运行。我看到很多人都遇到了与我类似的问题,我只需要对某些事情进行一些澄清。
基本上我有一个在主线程上运行的 NSTimer,它正在更新代表时间的图像,但我也有一个 mapView。当用户平移地图时,计时器被阻止。我的问题是,如果我创建一个新线程并将计时器添加到其运行循环中,当我执行选择器(更新 UI)时,这不会再次阻塞计时器线程吗?我也知道从辅助线程更新 UI 是不好的做法,那么我该如何处理呢?
更新:我认为mapView阻塞了计时器,因为它们都在同一个运行循环中运行。我现在已经用带有自己的运行循环的计时器线程修复了这个问题,但这导致了我遇到了第二个问题,这让我陷入了困境!这是代码...
//called when I need to restart the timer
[NSThread detachNewThreadSelector:@selector(resumeTimer) toTarget:self withObject:nil];
-(void) restartTimer {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
timer=[NSTimerscheduledTimerWithTimeInterval:1.
target:self
selector:@selector(dim)
userInfo:nil
repeats:YES];
[self performSelectorOnMainThread:@selector(timerImageUpdate)
withObject:nil
waitUntilDone:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
[pool drain];
}
此代码在 [池排水] 上给我一个 Bad_access 错误;
我已经在仪器中运行了代码,但仍然不明白为什么它会给我这个错误。有什么想法吗?
Ive been trying to get my game to work correctly with an NSTimer
. Ive seen many people have had a similar problem to me and I just need a bit of clarification on something.
Basically I have an NSTimer
running on the main thread which is updating images which represent the time, but I also have a mapView. When the user pans the map the timer is blocked. My question is if I create a new thread and add the timer to its runloop, when I perform selector (which updates UI) will this not block the timer thread again? Also I know it is bad practise to update the UI from secondary thread so how would I go about that?
UPDATE: I think the mapView was blocking the timer as they were both running in the same run loop. I have now fixed this with a timer thread with its own run loop, however this has led me to a 2nd problem which has me extremely stuck!! Here is the code...
//called when I need to restart the timer
[NSThread detachNewThreadSelector:@selector(resumeTimer) toTarget:self withObject:nil];
-(void) restartTimer {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
timer=[NSTimerscheduledTimerWithTimeInterval:1.
target:self
selector:@selector(dim)
userInfo:nil
repeats:YES];
[self performSelectorOnMainThread:@selector(timerImageUpdate)
withObject:nil
waitUntilDone:NO];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
[pool drain];
}
This code gives me a Bad_access error on the [pool drain];
I have run the code in instruments and still cannot see why it gives me the error. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您为计时器创建一个线程,您仍然需要在主线程上进行 UI 更新。您可以使用 performSelectorOnMainThread:withObject:waitUntilDone:NO 它将在主线程上对方法调用进行排队,而不会阻塞计时器线程。
但是,如果主线程的 runloop 被地图平移阻止(为什么?)UI 更新仍将在事件队列中等待,直到地图平移完成。
If you create a thread for your timer, you still have to do the UI update on the main thread. You can do that with performSelectorOnMainThread:withObject:waitUntilDone:NO which will queue the method call on the main thread without blocking the timer thread.
However, if the main thread's runloop is blocked by the map panning (why?) the UI update will still be waiting in the event queue for the until the map pan is done.