Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.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 NSTimer Uniqe问题_Iphone_Ios4_Iphone Sdk 3.0_Nstimer - Fatal编程技术网

Iphone NSTimer Uniqe问题

Iphone NSTimer Uniqe问题,iphone,ios4,iphone-sdk-3.0,nstimer,Iphone,Ios4,Iphone Sdk 3.0,Nstimer,我将直接讨论这个问题 这家伙一周来一直在吃我的头 我打算做的是设置我的计时器,它应该在主运行循环中从辅助线程启动。因此,我做如下 if(timerRefresh) { //[timerRefresh invalidate]; timerRefresh = nil; } if (!self.isConnectionAvailable) { timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInte

我将直接讨论这个问题

这家伙一周来一直在吃我的头

我打算做的是设置我的计时器,它应该在主运行循环中从辅助线程启动。因此,我做如下

if(timerRefresh)
{
    //[timerRefresh invalidate];
    timerRefresh = nil;
}

if (!self.isConnectionAvailable) {
    timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}
else if (self.isLivePresent||self.isUpcomingMatchToday) {
    timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}
else {
    timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
}

NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
[runLoop addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
[runLoop run];
当该命令触发时,加载程序开始加载主线程,处理工作在次线程上完成

我希望这是一个正确的方法

现在我在这个主类中有一个子类,当它触发一个过滤过程时,它也必须显示一个加载程序,所以为了避免多个加载程序,当过滤过程触发时,我通过从子类发送通知来暂停对这个父类的刷新..像这样

-(void)teamNameClicked:(id)sender
{
    BOOL result = YES;
    NSNumber *newNumber = [NSNumber numberWithBool:result];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"PauseMatchesLiveMatchTimer" object:newNumber];

    [self performSelector:@selector(sendTeamNameClickToFunction:) withObject:sender];
}
当操作完成时,我有另一个通知程序,如下所示

-(void)processTeamNameClick:(id)sender
{
    UIButton *button = (UIButton *)sender;
    selectedIndexDropDown  = button.tag;

    [self parseTeamFile:button.tag];
    self.lblDropDown.text = [dictTeamFilter valueForKey:[NSString stringWithFormat:@"%i",button.tag]];
    [tblResults performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

    BOOL result = NO;
    NSNumber *newNumber = [NSNumber numberWithBool:result];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"PauseMatchesLiveMatchTimer" object:newNumber];
}
请注意结果的“是”和“否”

现在我是通知的观察员

-(void)pauseAndResumeTimer:(NSNotification *)notification;
{
    NSNumber *newNumber = [notification object];
    BOOL result = [newNumber boolValue];

    if (result) {
        if(timerRefresh)
        {
            if ([timerRefresh isValid])
                [timerRefresh invalidate];
            timerRefresh = nil;
        }
    }
    else 
    {
        if(timerRefresh)
        {
            if ([timerRefresh isValid])
                [timerRefresh invalidate];
            timerRefresh = nil;
        }

        if (!self.isConnectionAvailable) {
            timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }
        else if (self.isLivePresent||self.isUpcomingMatchToday) {
            timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }
        else {
            timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
        }

        NSRunLoop *runLoop = [NSRunLoop mainRunLoop];
        [runLoop addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
        [runLoop run];
    }
}
当过滤过程开启时,我停止父计时器。当我离开的时候,我会重新开始

好的…现在问题来了。。。当我在我的页面上做正常的导航时,它工作得非常好。比如切换标签,在页面之间遍历等等

但如果我使用过滤过程,不知何故,它会触发主页上的计时器,甚至当视图消失时,似乎也会启动计时器事件。我想避免那样,但我不知道怎么做

如果有人能真正帮助我,请帮我。
提前感谢。

您的代码中有一些有趣的东西:

  • 首先也是最重要的一点,我至少90%肯定您不想在程序的任何方法中调用
    [[nsrunlop main runloop]run]
    ——这些方法是否已经退出,或者您是否一直在一个线程一个线程地聚合
  • 其次,您的计时器失效都有点奇怪:
  • if(timerRefresh)if([timerRefresh isValid])[timerRefresh invalidate]中没有使用;因为在目标C中,消息传递
    nil
    是非常好的。这样一条消息的结果总是
    0x0
    ,因此第一条
    if
    是不必要的,而第二条在这种情况下的计算结果是
    NO
  • 使计时器无效意味着将其从计划的运行循环中删除。因此,第二个
    if
    也是不必要的-只剩下
    [timerRefresh invalidate]
  • 要使
    -[NSTimer invalidate]
    生效,需要在调度计时器的线程上调用它。据我所知,并非所有方法都是如此。因此,您应该使用带有适当参数的
    performSelectorOnMainThread:withObject:waitUntilDone:
  • [self-performSelector:@selector(sendTeamNameClickToFunction:)with Object:sender]
    和简单的
    [self-sendTeamNameClickToFunction:sender]
    之间没有区别。除了后者更容易阅读;-)
  • pauseAndResumeTimer:
    中的
    if
    子句没有太多意义,即存在大量代码重复
这是一种整理的方法,失效发生在主线程上:

-(void)pauseAndResumeTimer:(NSNotification *)notification
{
    [timerRefresh performSelectorOnMainThread:@selector(invalidate) withObject:nil waitUntilDone:YES];
    timerRefresh = nil;

    NSNumber *result = [notification object];
    if ([result boolValue]) return;

    if ( !self.isConnectionAvailable || self.isLivePresent || self.isUpcomingMatchToday ) {
        timerRefresh = [NSTimer timerWithTimeInterval:appDelegate.TimerInterval target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
    } else {
        timerRefresh = [NSTimer timerWithTimeInterval:LongRefresh target:self selector:@selector(startAutoRefresh) userInfo:nil repeats:NO];
    }

    [[NSRunLoop mainRunLoop] addTimer:timerRefresh forMode:NSDefaultRunLoopMode];
}

谢谢你的见解,dany.但问题是,我还没有在这里向你展示完整的代码,用于良好的组织目的。暂停和恢复计时器通知方法是我避免过多加载程序的唯一方法。看这里有两门课。类A和B。A是父类,B是其子类。A从服务器执行主要的获取和解析操作,并将其传递给B以执行显示操作。当我做一个过滤过程时,B有它自己的小的抓取和解析操作。现在当我做这个解析和抓取操作时,我必须显示一个加载器。这个过程必须在用户选择的一定时间间隔后重复。同样,可能没有连接问题,因此也必须检查。现在,正如A定期解析和加载一样,例如30秒,如果在这段时间内用户在B上踢一个过滤器操作部分,它将显示自己的加载程序。如果在A的刷新到期时发生这种情况,它会在短时间内显示两个连续的加载程序,这会让用户感到困惑。为了避免这种情况发生,我设计了这个通知方案,但这似乎打乱了我的计时器逻辑。当我完成一个刷新周期时,同样的计时器进程代码也适用。我是这样做的,而不是正常的定时器cos调度,这是一个国际应用程序,并不是每个地方都有快速连接,因此在Edge上加载数据可能需要一段时间,刷新周期可能太小,因为它是由用户设置的。如果加载进程在后台线程上,它没有完成,并且主线程上的计时器导致另一个进程启动,因为时间间隔已经到了,它会导致我的应用程序崩溃,因为数据太多了。希望现在你对我的问题有了更清晰的认识,如果你能帮我为同样的问题构建计时器代码。哦,是的。。只是要清楚,对于你的第三颗子弹,我知道没有什么区别,只是我的装载机功能可以踢进去,其他的聪明我看不到装载机。因为它也在主线程上:)