Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何在nsrunlop中正确使计时器无效_Iphone_Nstimer_Dealloc_Invalidation_Nsrunloop - Fatal编程技术网

Iphone 如何在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

我从应用程序中的服务器获取具有第二个结束值的信息,并在收到此信息后启动计数器

我的项目包含一个scrollview,因此为了避免由于滚动而锁定我的计时器,我通过以下方式将计时器添加到nsrunlop:

[[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验证。