3

我在一个类中使用这个方法来启动一个动作:

[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];
}

调用 stopRolling 方法的方法是使用 performOnMainThread 调用的:

谢谢。

- 编辑 - -

我已经根据建议修改了方法,但仍然无法正常工作:

-(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];

}

感谢一切。

4

1 回答 1

4

更改传递给两个方法的参数,如图所示,

[self performSelector:@selector(SampleMethod) withObject:self afterDelay:delayTime];     
[NSObject cancelPreviousPerformRequestsWithTarget:self];       
于 2013-10-01T06:26:14.297 回答