Jac*_*ch0 7 model-view-controller cocoa-touch objective-c nstimer
我正在尝试基于MVC模型实现秒表.
秒表使用NSTimer,-(void) tick每次超时都会调用选择器.
我试图将秒表作为可重用性的模型,但是我遇到了一些关于如何为每个滴答更新视图控制器的设计问题.
首先,我使用tick方法创建了一个协议,并使视图控制器成为委托.然后,视图控制器根据每个刻度线上的计时器属性更新视图.elapsedTime是一个只读的NSTimeInterval.
它有效,但我认为这可能是糟糕的设计.我是Objective-C/Cocoa Touch初学者.我应该使用像KVO这样的东西吗?或者是否有更优雅的解决方案让模型通知elapsedTime已更改的视图控制器?
计时器是确保定期更新用户界面但不使用它来跟踪时间的好方法.NSTimer可以漂移,如果使用计时器累积秒数,任何小错误都会累积.
相反,使用NSTimer来触发更新UI的方法,但使用NSDate获取实时.NSDate将为您提供毫秒级的分辨率; 如果你真的需要更好,请考虑这个建议使用Mach的定时功能.因此,使用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];
}
Run Code Online (Sandbox Code Playgroud)
如果允许重新启动等,您的代码可能会更复杂一些,但重要的是您没有使用NSTimer来测量总耗用时间.
您可以在此SO线程中找到其他有用的信息.
最近,我一直在使用 using 块而不是普通的旧@selector块。它创建更好的代码并将逻辑保持在同一位置。
中没有原生块支持,但我使用了https://gist.github.com/250662/d4f99aa9bde841107622c5a239e0fc6fa37cb179NSTimer中的类别
如果没有返回选择器,您可以将代码保留在一处:
__block int seconds = 0;
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:1
repeats:YES
usingBlock:^(NSTimer *timer) {
seconds++;
// Update UI
if (seconds>=60*60*2) {
[timer invalidate];
}
}];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
882 次 |
| 最近记录: |