【发布时间】:2012-03-09 18:58:07
【问题描述】:
我在一个类中使用这个方法来启动一个动作:
[self performSelector:@selector(startRolling) withObject:nil afterDelay:0.1f];
为了阻止它,我正在使用:
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
但永远不会停止。
两个调用都在同一个类和同一个线程中实现。
这个我也用过,但是没解决:
-(void)stopRolling
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(commitAnimation) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
}
我错过了什么?
谢谢。
---编辑---
要知道我正在使用的是否是主线程:
-(void)stopRolling
{
if ([NSThread isMainThread])
NSLog(@"Is Main Thread");
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(commitAnimation) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
}
什么时候工作正常,什么时候不总是出现在日志中是主线程。
我正在启动的选择器(startRolling 和 commitAnimations)是使用 [UIView beginAnimation:context:) 的动画
可能是这个原因吗?
方法如下:
-(void)startRolling
{
currentPic++;
if (currentPic > count)
currentPic = 1;
[UIView beginAnimations:@"fadeIn" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:RDFadeInDelay];
NSLog(@"RollUp: %@",[NSString stringWithFormat:@"RDInitialRollUp_%d",currentPic]);
background.image = [UIImage imageNamed:[NSString stringWithFormat:@"RDInitialRollUp_%d.jpg",currentPic]];
background.alpha = 1.0f;
[UIView commitAnimations];
}
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *) finished context:(void *) context
{
if ([animationID isEqualToString:@"fadeIn"])
{
[self performSelector:@selector(commitAnimation) withObject:nil afterDelay:RDOnScreenDelay];
}
else
{
[self performSelector:@selector(startRolling) withObject:nil afterDelay:0.1f];
}
}
-(void)commitAnimation
{
[UIView beginAnimations:@"fadeOut" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:RDFadeOutDelay];
background.alpha = 0.0f;
[UIView commitAnimations];
}
-(void)stopRolling
{
if ([NSThread isMainThread])
NSLog(@"Is Main Thread");
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(commitAnimation) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
}
正在使用 performOnMainThread 调用调用 stopRolling 方法的方法:
谢谢。
---编辑---
我已经根据建议修改了方法,但仍然无法正常工作:
-(void)stopRolling
{
if ([NSThread isMainThread])
NSLog(@"Is Main Thread");
else
NSLog(@"Is NOT Main Thread");
[self.layer removeAllAnimations];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(commitAnimation) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget:self];
}
我观察到,如果用户在执行图像之间的转换时点击屏幕,则当它不起作用时。但是如果用户在图像显示在屏幕上时(2 秒内)点击屏幕,一切正常。
始终在主线程上。
:(我绝望了,这让程序因为内存崩溃了。
--编辑--
最后我已经使用 BOOL 标志解决了。但我认为这是一个糟糕的解决方案,因为这必须在没有的情况下工作。正在执行动画时发生了一些奇怪的事情,因为这仅在动画未执行时才有效。
这适用于所有情况:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *) finished context:(void *) context
{
if (!mustAnimate) return;
if ([animationID isEqualToString:@"fadeIn"])
{
[self performSelector:@selector(commitAnimation) withObject:nil afterDelay:RDOnScreenDelay];
}
else
{
[self performSelector:@selector(startRolling) withObject:nil afterDelay:0.1f];
}
}
-(void)commitAnimation
{
[UIView beginAnimations:@"fadeOut" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:RDFadeOutDelay];
background.alpha = 0.0f;
[UIView commitAnimations];
}
-(void)stopRolling
{
mustAnimate = NO;
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(commitAnimation) object:nil];
}
感谢一切。
【问题讨论】:
-
你确定你检查了线程吗?它应该可以工作...设置更大的延迟以查看它是否工作如何?
-
在几次测试中,我观察到有时会停止,有时不会。但最令人好奇的是,曾经做过同样的事情。我对这件事真的很迷茫。感谢您的回答。
-
请确保您始终在同一个线程上...
-
我已经编辑了有关该问题的更多详细信息。谢谢。
-
所以,它总是发生在主线程上,并且您删除所有动画...当您观察它停止的时间时,您记录了时间吗?比如它实际发生的时间和它告诉它取消的时间?
标签: objective-c performselector