Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ios更新在计时器上显示_Ios_Objective C_Nstimer_Viewdidload_Uiapplicationdelegate - Fatal编程技术网

ios更新在计时器上显示

ios更新在计时器上显示,ios,objective-c,nstimer,viewdidload,uiapplicationdelegate,Ios,Objective C,Nstimer,Viewdidload,Uiapplicationdelegate,我有一个比较复杂的iOS用户界面,我需要每秒重新加载UICollectionView的一个特定单元格以显示时间(有点像复杂的秒表),在这个调用中,我还需要每秒做一些其他事情 问题第一部分 我的问题是解决这类问题的最佳实践是什么 选项1(使用递归调用) 选项2(使用NSTimer) 问题的第2部分 在这两种情况下,启动和终止这些循环的最佳位置是什么 如果我把它们放在ViewDidLoad中,即使我已经离开了相关视图,它们也会继续被调用,我宁愿只在需要的时候让循环运行。另一方面,每次显示视图时,

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

问题第一部分
我的问题是解决这类问题的最佳实践是什么

选项1(使用递归调用)

选项2(使用NSTimer)

问题的第2部分


在这两种情况下,启动和终止这些循环的最佳位置是什么

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


我猜有一个解决方案涉及到“ViewWillExample”和“ViewWillEnglishe”,但我对不调用其中一个的情况持谨慎态度。我也不想通过做出任何错误的假设来产生多个循环。

对于第1部分

我建议使用计时器。主要原因是您可以通过使计时器无效来停止进程。使用performSelector,您可以实现类似的效果,但我不会这样做。每个人都有自己的

对于第2部分

您确实希望使用
viewwillbeen
(或
viewdidebeen
)和
viewdidefine
(或
viewwilldefine
)。将计时器设置为“出现”,并在“消失”时将其拆下

退房


希望这能让你明白一些事情,并解决你的“但我不愿意陷入一个或另一个没有被呼叫的情况。”关注

虽然
NSTimer
会起作用,但它并不是专门用来制作秒表之类的东西。您不能依赖它每秒触发一次,因此您仍然需要使用
NSDate
对象和类似
timeintervalscencedate
的内容来计算计时器每次触发时要显示的值。这样,如果秒表在一秒钟或更长时间内没有着火,它就可以赶上

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

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

只需创建一个带有start、calcTime(可能还有stop、reset和resume)的自定义计时器类。调用start时,对象只需获取当前日期/时间(NSDate)并将其存储。调用calcTime时,只需再次获取当前日期/时间,使用
TimeIntervalsIncestDate
计算经过的时间,然后返回值或设置可读取的属性

在后台线程中,只需继续调用
calcTime
方法并通过
dispatch\u async(dispatch\u get\u main\u que)(
)更新UI,然后在调用之间休眠大约100毫秒。您可以检查布尔全局变量以查看是否应继续运行

如果处理器被挂起,后台线程仍然可能陷入困境,然而,这种情况发生的可能性要比主运行循环繁忙的可能性小,而主运行循环正是繁忙的原因


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

计时器将为您提供更精确的1秒间隔。当您关闭任何东西时,计时器也更容易停止,这样您就不会因为试图调用不存在的
self
上的函数而崩溃。如果选择了这个选项,我就不会进行递归。有没有理由NSTimer更“准确”呢?我没有研究过它,但我的假设是,在某一点上,带day的performSelector将使用与NSTimer相同的机制。这将更准确,因为使用递归时,您运行的是一堆需要时间的代码,然后再将单个计时器设置一秒钟(超过代码执行时间)。NSTimer每秒关闭一次(除非它没有足够的CPU时间,在这种情况下,它只会“中断帧”并在这里和那里跳过调用)。这是我的全部经验,我没有任何文档来支持这些。运行了这两个实现后,NSTimer看起来更准确。大约一个数量级。当递归调用每秒发生一次时,它通常会关闭大约0.01到0.02秒。NSTimer看起来只有0.001关闭,而且有时也会关闭。是的,这确实有帮助。这是一个很好的答案。我肯定倾向于NSTimer方法。我在使用ViewDidDisplay和ViewDidEnglishe时仍然遇到问题。退出应用程序后,当应用程序打开时,不会调用ViewDidDisplay。这是一个问题吗?或者计时器是否仍在从上一个ViewDidDisplay调用运行?我可以相信。你的viewcontroller应该在进入后台时进行监控。这里有一个方法来解决这个问题。是的,这真是个好消息。我绝对不会使用NSTimer来跟踪实际时间。我一直在使用NSDate对象进行跟踪。我只使用此NSTimer启动显示更新循环。
- (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];
        
    });
}
- (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)
}