0

我有一个有点复杂的 iOS 用户界面,我需要每秒重新加载 UICollectionView 的特定单元格以显示时间(有点像复杂的秒表),我还需要在这个调用中每秒做一些其他事情.

问题的第 1 部分


我的问题是解决此类问题的最佳做法是什么?

选项 1(使用递归调用)

- (void)viewDidLoad
{
   [self runUpdateDisplayLoop];
}
- (void)runUpdateDisplayLoop
{
   //do stuff (reload cell, etc)
       
   //Recurissively Call Every Second
    dispatch_async(dispatch_get_main_queue(), ^{
        
        [self performSelector:@selector(runUpdateDisplayLoop) withObject:nil afterDelay:1.0];
        
    });
}

选项 2(使用 NSTimer)

- (void)viewDidLoad
{
   NSTimer *updateDisplayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                              target:self 
                                            selector:@selector(runUpdateDisplayLoop:) 
                                            userInfo:nil 
                                             repeats:YES];
}

- (void)updateDisplayLoop:(NSTimer *) theTimer
{
 //do stuff (reload cell, etc)
}

问题的第 2 部分


无论哪种情况,启动和终止这些循环的最佳位置是什么?

如果我将它们放在 ViewDidLoad 中,即使我已经离开相关视图,它们也会继续被调用,我宁愿只在需要时运行循环。另一方面,每次显示视图时都必须运行循环(即使视图已以各种方式关闭 - 应用程序关闭并重新打开、电话中断等)。关于应用程序生命周期,我的目标是 iOS 5 和 iOS 6。

我猜有一个涉及“viewWillAppear”和“viewWillDisappear”的解决方案,但我对进入其中一个或另一个不被调用的情况持怀疑态度。我也不想通过做出任何错误的假设来产生多个循环。

4

2 回答 2

1

虽然NSTimer会起作用,但它并不是真正用于创建秒表等。你不能依赖它每秒触发一次,所以你仍然需要使用一个NSDate对象和类似的东西timeIntervalSinceDate来计算每次触发时要为计时器显示的值。这样,如果您的秒表碰巧在一秒或多秒内没有触发,您的秒表就可以赶上。

NSTimer 事件由主运行循环处理,如果主运行循环很忙,则不会触发事件。

我更喜欢后台线程的想法。但是,您不需要递归来使其工作。

只需创建一个自定义 Timer 类,其中包含 start、calcTime(可能还有 stop、reset 和 resume)。当您调用 start 时,对象应该简单地获取当前日期/时间 (NSDate) 并存储它。当您调用 calcTime 时,只需再次获取当前日期/时间,使用 计算经过的时间timeIntervalSinceDate,然后返回值或设置您可以读取的属性。

在后台线程中,只需继续调用该calcTime方法并通过 更新 UI dispatch_async(dispatch_get_main_que)(),然后在两次调用之间休眠大约 100 毫秒。你可以检查一个布尔全局变量,看看你是否应该继续运行。

如果处理器被固定,后台线程仍然可能陷入困境,但是,与主运行循环繁忙相比,这种情况发生的可能性较小,而主运行循环是造成如此多的原因。

我创建了一个秒表应用程序,这是我在确定 NSTimer 不可行后使用的方法。

于 2013-06-28T21:00:11.577 回答
1

1 部分

我建议使用计时器。主要原因是您可以通过使计时器无效来停止该过程。使用 performSelector 你可以实现类似的东西,但我不会走那条路。各有各的。

2 部分

您确实想使用viewWillAppear(or viewDidAppear) 和viewDidDisappear(or viewWillDisappear)。在出现时设置计时器并在消失时将其拆除。

查看响应显示通知

希望能够阐明事情并解决您的问题,“但我对进入其中一个或另一个不被调用的情况持怀疑态度。” 关心

于 2013-06-28T18:22:41.887 回答