objective-c - 秒表的观察者模式

标签 objective-c cocoa-touch model-view-controller nstimer

我正在尝试实现基于 MVC 模型的秒表。

秒表使用 NSTimer,每次超时都会调用选择器 -(void) tick

我试图将秒表作为可重用性的模型,但我遇到了一些关于如何为每个刻度更新 View Controller 的设计问题。

首先,我使用 tick 方法创建了一个协议(protocol),并将 View Controller 作为其委托(delegate)。然后 View Controller 根据计时器的属性在每次滴答时更新 View 。 elapsedTime 是只读的 NSTimeInterval。

它有效,但我认为它可能是糟糕的设计。我是 Objective-C/Cocoa Touch 初学者。我应该使用像 KVO 这样的东西吗?或者是否有更优雅的模型通知 View Controller elapsedTime 已更改的解决方案?

最佳答案

计时器是确保您定期更新用户界面的好方法,但不要用它来跟踪时间。 NSTimer can drift ,如果您使用计时器来累积秒数,任何小错误都会累积起来。

相反,使用 NSTimer 触发更新 UI 的方法,但使用 NSDate 获取实时时间。 NSDate 会给你毫秒分辨率;如果你真的需要更好的,请考虑 this suggestion to use Mach's timing functions .所以,使用 NSDate,你的代码可能是这样的:

- (IBAction)startStopwatch:(id)sender
{
    self.startTime = [NSDate date];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 
                                                  target:self
                                                selector:@selector(tick:)
                                                userInfo:repeats:YES];
}

- (void)tick:(NSTimer*)theTimer
{
    self.elapsedTime = [self.startTime timeIntervalSinceNow];
    [self updateDisplay];
}

- (IBAction)stopStopwatch:(id)sender
{
    [self.timer invalidate];
    self.timer = nil;
    self.elapsedTime = [self.startTime timeIntervalSinceNow];
    [self updateDisplay];
}

如果您允许重新启动等,您的代码可能会更复杂一些,但这里重要的是您没有使用 NSTimer 来测量总耗时。

您将在 this SO thread 中找到更多有用信息.

关于objective-c - 秒表的观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8218514/

相关文章:

ios - 在电子邮件中放入可在 iPhone 或 iPad 上打开应用程序的 URL

java - 如何将带有斜杠的 URL 重定向到没有斜杠的相应 URL?

iphone - 如果你有很多静态数据,如何遵循 MVC?

ios - Mach-O 链接器错误,将 xcode 升级到 8.0 后未定义的体系结构符号

objective-c - 编辑 100 个 ImageViews - Objective C iOS

ios - 如何将 JSON 中返回的图像 URL 显示为 UITableViewCell 的缩略图

objective-c - 沙箱和保存文件

iphone - 使用#pragma 消息时如何禁用警告?

ios - 如何在 UITextView 中默认显示键盘?

asp.net-mvc - MVC 逻辑、 View 和助手 - 一个具体的故事