线程和NSTimer [英] Thread and NSTimer

查看:98
本文介绍了线程和NSTimer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个有计时器的应用程序。我计算从给定时间到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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆