问题描述
我正在制作一个有计时器的应用程序。我计算从给定时间到0的分钟和秒数。当发生这种情况时,我会启动一个警报视图。
我的结构是:
Mainthread方法分配一个新线程并初始化它。
线程的入口点(方法)有一个计时器,它调用一个计算剩余时间的方法,如果时间到了,则显示一个警报视图。
但是,这是正确的吗?因为现在我从另一个线程更新GUI而不是主...这是不对的?我也在这个帖子中显示一个alertview。
我想过制作另一个方法来封装所有用于更新和显示alertview的逻辑,并且在nstimer调用的方法中使用performSelectorInMainThread,但是这是正确的吗? / p>
感谢您的时间。
假设它相当简单确定剩下多少时间,只需在主线程上运行你的计时器。计时器附加到当前的runloop,因此它不会阻塞任何地方,并且它的回调方法不应该花费过多的时间来运行,因此可以很好地更新UI。
- (void)initializeTimerWithEndTime:(NSDate *)endTime
{
//在主线程&上调用它它会自动
//为你安装主runloop上的计时器
self.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(timerTick: )
userInfo:endTime
重复:是];
#if __TARGET_OS_IPHONE__
//跟踪触摸时触发
[[NSRunLoop mainRunLoop] addTimer:self.countdownTimer
forMode:UITrackingRunLoopMode];
#else
//跟踪鼠标事件时触发
[[NSRunLoop mainRunLoop] addTimer:self.countdownTimer
forMode:NSEventTrackingRunLoopMode];
//显示应用程序模式面板/警报时触发
[[NSRunLoop mainRunLoop] addTimer:self.countdownTimer
forMode:NSModalPanelRunLoopMode];
#endif
}
- (无效)cancelCountdown
{
[self.countdownTimer invalidate];
self.countdownTimer = nil;
}
- (void)timerTick:(NSTimer *)aTimer
{
NSDate * endDate = [timer userInfo];
NSDate * now = [NSDate date];
//我们已经过了结束日期吗?
if([endDate laterDate:now] == now)
{
// show alert
[self cancelCountdown];
返回;
}
//否则,计算单位&显示那些
NSUInteger单位= NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents * comps = [[NSCalendar currentCalendar]组件:单位
fromDate:[NSDate date]
toDate:endDate
options:0];
[self.clockView setHours:comps.hour
分钟:comps.minute
秒:comps.second];
}
I am making an application that has a timer. I count the minutes and seconds from a given time down to 0. When this happen I launch an alertview.
My structure is this:
Mainthread method allocate a new thread and initialize it.The entrypoint(method) for the thread has a timer which invokes a method for calculating time left, and if the time is up, displays an alertview.
However, is this correct? Because now I am updating GUI from another thread than the main...and that is bad right? And I am also displaying an alertview from this thread.
I thought of making another method that encapsulate all the logic for updating and displaying the alertview and in the method that the nstimer invokes use the performSelectorInMainThread, however is this correct?
Thanks for your time.
Assuming that it's fairly simple to determine how much time is left, just run your timer on the main thread. The timer gets attached to the current runloop, so it's not blocking anywhere, and its callback method shouldn't take an inordinate amount of time to run, and can therefore update the UI nicely.
- (void) initializeTimerWithEndTime: (NSDate *) endTime
{
// call this on the main thread & it'll automatically
// install the timer on the main runloop for you
self.countdownTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(timerTick:)
userInfo: endTime
repeats: YES];
#if __TARGET_OS_IPHONE__
// fire while tracking touches
[[NSRunLoop mainRunLoop] addTimer: self.countdownTimer
forMode: UITrackingRunLoopMode];
#else
// fire while tracking mouse events
[[NSRunLoop mainRunLoop] addTimer: self.countdownTimer
forMode: NSEventTrackingRunLoopMode];
// fire while showing application-modal panels/alerts
[[NSRunLoop mainRunLoop] addTimer: self.countdownTimer
forMode: NSModalPanelRunLoopMode];
#endif
}
- (void) cancelCountdown
{
[self.countdownTimer invalidate];
self.countdownTimer = nil;
}
- (void) timerTick: (NSTimer *) aTimer
{
NSDate * endDate = [timer userInfo];
NSDate * now = [NSDate date];
// have we passed the end date?
if ( [endDate laterDate: now] == now )
{
// show alert
[self cancelCountdown];
return;
}
// otherwise, compute units & show those
NSUInteger units = NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit;
NSDateComponents * comps = [[NSCalendar currentCalendar] components: units
fromDate: [NSDate date]
toDate: endDate
options: 0];
[self.clockView setHours: comps.hour
minutes: comps.minute
seconds: comps.second];
}
这篇关于线程和NSTimer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!