Iphone 如何在nsrunlop中正确使计时器无效
我从应用程序中的服务器获取具有第二个结束值的信息,并在收到此信息后启动计数器 我的项目包含一个scrollview,因此为了避免由于滚动而锁定我的计时器,我通过以下方式将计时器添加到nsrunlop:Iphone 如何在nsrunlop中正确使计时器无效,iphone,nstimer,dealloc,invalidation,nsrunloop,Iphone,Nstimer,Dealloc,Invalidation,Nsrunloop,我从应用程序中的服务器获取具有第二个结束值的信息,并在收到此信息后启动计数器 我的项目包含一个scrollview,因此为了避免由于滚动而锁定我的计时器,我通过以下方式将计时器添加到nsrunlop: [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 我创建了一个名为how original的NSTimer属性timer,这是我的start
[[NSRunLoop currentRunLoop] addTimer:timer
forMode:NSRunLoopCommonModes];
我创建了一个名为how original的NSTimer属性timer,这是我的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];
但它不会失效吗?我做错了什么?您应该先调用
[timer release]
,然后调用timer=nil
。在dealoc方法中也是如此。如果外部对象位于AUTLease池中,可能不会立即调用dealloc方法。在这些情况下,当系统决定最终删除对象时,会调用它。因此可能需要一些时间(如果设置断点)
顺便说一句,我建议避免使用逗号语法,而是使用大括号内的块。它更容易阅读。您应该首先调用
[timer release]
,然后调用timer=nil
。在dealoc方法中也是如此。如果外部对象位于AUTLease池中,可能不会立即调用dealloc方法。在这些情况下,当系统决定最终删除对象时,会调用它。因此可能需要一些时间(如果设置断点)
顺便说一句,我建议避免使用逗号语法,而是使用大括号内的块。阅读起来容易得多。这些逗号分隔的语句执行的顺序是什么?当您调用invalidate或调用release时,如果_timer为nil,会发生什么情况
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
试试这个,不需要检查计时器是否已经为零。如果为nil,则方法调用不执行任何操作
if ([_timer isValid]) {
[_timer invalidate];
}
[_timer release];
在dealloc方法中,不需要设置_timer=nil,在该方法结束后,其存储将消失。这些逗号分隔的语句以什么顺序执行?当您调用invalidate或调用release时,如果_timer为nil,会发生什么情况
if (_timer || [_timer isValid]) [_timer invalidate], _timer = nil, [_timer release];
试试这个,不需要检查计时器是否已经为零。如果为nil,则方法调用不执行任何操作
if ([_timer isValid]) {
[_timer invalidate];
}
[_timer release];
在dealloc方法中,不需要设置_timer=nil,它的存储在该方法结束后就消失了。我想我用过一次块,还有一些动画代码。在这种情况下,您将如何使用它?release和nil的切换并没有修复它,顺便说一句:(我想我误读了你关于块的评论,你的意思是:NSTimer*timer={[[NSTimer alloc]initWithFireDate:[NSDate date]interval:1.0目标:自选择器:@selector(timer:)userInfo:nil repeats:YES]};是的,没有函数式编程意义上的块,只是构造代码-抱歉,有点模棱两可:-)正如progrmr所说,我不确定它是否是从左到右执行的。但似乎还有另一个问题。结果是什么,计时器方法调用的频率是它应该调用的两倍吗?你能将实现更改为重用计时器而不是删除并重新创建它吗?看看这个addTimer调用可能会增加释放计数。运行循环retains定时器。在您使其失效之前,它不会释放它,因此在dealloc中执行invalidate是毫无意义的(dealloc直到上一个版本才会被调用)。我想我曾经使用过块,带有一些动画代码。在这种情况下,您将如何使用它?release和nil的切换没有修复它。顺便说一句:(我想我误读了你关于块的评论,你的意思是:NSTimer*timer={[[NSTimer alloc]initWithFireDate:[NSDate date]间隔:1.0目标:自选择器:@selector(计时器:)userInfo:nil repeats:YES]};是的,没有函数式编程意义上的块,只是构造代码-抱歉,有点模棱两可:-)正如progrmr所说,我不确定它是否是从左到右执行的。但似乎还有另一个问题。结果是什么,计时器方法调用的频率是它应该调用的两倍吗?你能将实现更改为重用计时器而不是删除并重新创建它吗?看看这个addTimer调用可能会增加释放计数。运行循环retains计时器。在您使其无效之前,它不会释放它,因此在dealloc中执行invalidate是没有意义的(dealloc直到上一个版本才会被调用)。我尝试过,但没有运气。它在除dealloc之外的任何方法中都有效,但不知何故,它感觉好像有第二个计数器潜入了某个地方。但我更改了代码,将计时器添加到可变数组中,计数始终为1。可变数组将保留计时器,除非您释放该数组,否则它将永远不会被释放。我我试过了,但运气不好。它在除dealloc之外的任何方法中都能工作,但不知何故,它感觉好像有第二个计数器潜入了某个地方。但是我更改了代码,将计时器添加到可变数组中,计数始终为1。可变数组将保留计时器,并且除非您释放该数组,否则它将永远不会被释放。是您的d吗正在调用ealloc?使用断点或在此处添加NSLog验证。是否正在调用dealloc?使用断点或在此处添加NSLog验证。