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上加载数据可能需要一段时间,刷新周期可能太小,因为它是由用户设置的。如果加载进程在后台线程上,它没有完成,并且主线程上的计时器导致另一个进程启动,因为时间间隔已经到了,它会导致我的应用程序崩溃,因为数据太多了。希望现在你对我的问题有了更清晰的认识,如果你能帮我为同样的问题构建计时器代码。哦,是的。。只是要清楚,对于你的第三颗子弹,我知道没有什么区别,只是我的装载机功能可以踢进去,其他的聪明我看不到装载机。因为它也在主线程上:)