如何正确地使 NSRunLoop 中的计时器无效
我从应用程序中的服务器获取带有秒数到结束值的信息,并在收到此信息后启动计数器。
我的项目包含一个滚动视图,因此为了避免因滚动而锁定计时器,我通过以下方式将计时器添加到 NSRunLoop 中:
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
我创建了一个名为 NSTimer 的属性,多么原始,计时器,这是我的 startTimer 函数的整个片段:
- (void)startTimer
{
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
NSTimer * timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:1.0
target:self
selector:@selector(timer:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
[self setTimer:timer];
[timer release];
}
在start方法中检查无效的原因是因为在secondsToEnd值达到0后,我收到了一个新值,然后我再次调用startTimer。
在我的 dealloc 方法中,我有这个:
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
但它不会失效?我做错了什么?
I get information from a server in my app with a secondsToEnd value and I start a counter after I've received this information.
My project contains a scrollview, so to get around locking my timer due to scrolling around I add the timer to the NSRunLoop in the following way:
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
I made a NSTimer property called, how original, timer and this is the whole snippet of my startTimer function:
- (void)startTimer
{
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
NSTimer * timer = [[NSTimer alloc] initWithFireDate:[NSDate date]
interval:1.0
target:self
selector:@selector(timer:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
[self setTimer:timer];
[timer release];
}
The reason for the check to invalidate in the start method is because after the secondsToEnd value hits 0, I receive a new one and I call startTimer again.
And in my dealloc method I have this:
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
But it doesn't get invalidated? What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这些逗号分隔的语句以什么顺序执行?当你调用 invalidate 或调用 release 时,如果 _timer 为 nil 会发生什么?
试试这个,不需要检查 _timer 是否已经为零。如果它为零,则该方法调用不执行任何操作。
在dealloc方法中不需要设置_timer = nil,该方法结束后它的存储就消失了。
What order do these comma separated statements execute in? What happens if _timer is nil when you call invalidate or when you call release?
Try this instead, there is no need to check whether _timer is already nil. If it was nil then the method call does nothing.
In the dealloc method there is no need to set _timer = nil, its storage is gone after this method ends.
您应该首先调用
[timer release]
,然后调用timer = nil
。与 dealloc 方法相同。如果外部对象位于 autrelease 池中,则 dealloc 方法可能不会立即被调用。在这些情况下,当系统决定最终删除您的对象时会调用它。所以可能需要一些时间(如果你设置了断点)。顺便说一句,我建议避免使用逗号语法并使用大括号内的块。它更容易阅读。
You should first call
[timer release]
and thentimer = nil
. Same in dealloc method. The dealloc method might no get called immediately if outer objects are in autrelease pools. In these cases it is called when the system decides to drop your object finally. So it may take some time (if you set a breakpoint).BTW I would suggest to avoid comma syntax and use blocks within curly braces instead. It's far more easier to read.