【问题标题】:How to keep NSTimer alive?如何保持 NSTimer 活着?
【发布时间】:2012-03-20 13:36:43
【问题描述】:
我的应用程序中有 2 个视图控制器,从第一个视图导航到下一个视图时,有一个名为 startTimer 的按钮,在单击 startTimer 时作为选择器方法作为选择器方法,计时器在 HH:mm:ss 中启动 格式,我没有使计时器失效,但是当我返回第一个 viewController 并再次返回第二个 viewController 并且如果我按下 startTimer 按钮时,计时器再次从 0 开始,但我希望它保留以前的价值,我怎样才能做到这一点?我知道,由于我再次加载 viewController,笔尖将重新加载到内存中,但我怎样才能保留计时器标签和计时器值?
任何帮助都提前表示感谢。谢谢。
【问题讨论】:
标签:
iphone
objective-c
ios
xcode4
nstimer
【解决方案1】:
通过将数据放入视图控制器,您破坏了 MVC(模型-视图-控制器)。此外,您要求一个没有可靠时间承诺的机制 (NSTimer) 为您跟踪时间。 NSTimer 不会在您请求的时间间隔完全触发。它可以在该间隔之后的任意点触发。 使用NSTimer 作为秒表几乎总是会浪费时间(有时会浪费很多时间,尤其是在有滚动视图的情况下)。(最后一点被夸大了。重复计时器会正确地安排自己所以赢了'通常不会浪费时间。如果完全跳过重复,您只会浪费时间,这可能发生在长滚动或其他可以让计时器持续一秒的情况下。)
创建一个新的模型对象来保存秒表信息。我们称之为Stopwatch。假设您需要它是可启动和可停止的,它需要一个NSTimeInterval accumulatedTime 属性和一个NSDate lastStarted 属性(如果您愿意,您也可以将lastStarted 设置为NSTimeInterval)。因此,要启动秒表,请将lastStarted 设置为“现在”。要停止秒表,请清除 lastStarted 并将当前累计时间移动到 accumulatedTime。要找出当前时间,请将accumulatedTime 添加到now - lastStarted。
好的,既然你有了它,你能用它做什么?您可以将它传递给您的视图控制器,他们可以询问“当前的秒表值是多少?”他们可以随心所欲地启动和停止它。
现在您的视图控制器希望每秒更新一次它的显示,所以您有一个计时器来执行此操作。它每秒都会询问秒表,“现在是什么时间”并显示它。但它没有设置时间。它只是问。
顺便说一句,您也可以在 Stopwatch 上使用 KVO,但它有点棘手,因为 Stopwatch 需要运行自己的计时器来发送更改通知。我通常觉得这比它的价值更麻烦。
【解决方案2】:
不要那样做,这样每次你加载包含 NSTimer 的视图时,都会创建一个新的 NSTimer 对象,而旧的对象仍然在内存中,因为你没有使它失效。
最好的方法是你必须将 NSTimer 放在 Application Delegate 中,然后只有在你第一次加载那个 View Controller 时才启动它。
为此,您必须设置一个标志来检查视图是否第一次加载。
【解决方案3】:
如果 NSTimer 是您的实例变量之一,我想您可以检查一下它是否已分配。
//NSTimer *timer; declare this in your interface
if (timer==nil)
{
// allocate timer
}
//Do nothing if it is allocated all ready
【解决方案4】:
我要做的是将第二个视图控制器作为第一个视图控制器的 ivar。这样,您只需实例化一次,您的 NSTimer 将保留在内存中。
然而,如果你想保持你的风格,你应该在任何类型的偏好中保存当前时间(查看[NSUserDefaults standardUserDefaults] 或创建你自己的单例类)。然后在视图中从您的第二个视图控制器加载方法,加载该值并将其添加为您的计时器的偏移量。
希望能提供帮助!