CancelPreviousPerformRequestsWithTarget not working

I use this method in the class to start the action:

[self performSelector:@selector(startRolling) withObject:nil afterDelay:0.1f];

      

To stop it I use:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startRolling) object:nil];

      

But it never stops.

Both calls are implemented in the same class and on the same thread.

I've used this too, but it doesn't solve:

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

      

What am I missing?

Thank.

--- EDIT ---

To find out if the main thread I'm using is:

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

      

When it works fine, and when it doesn't always appear in the log, the main topic is displayed.

What the selector I'm running (startRolling and commitAnimations) do is animations using [UIView beginAnimation: context :)

Is it possible that this is the reason?

Here's the methods:

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

      

A method is called that calls the stopRolling method using performOnMainThread:

Thank.

- EDIT ---

I changed the method with suggestions but still didn't work:

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

      

I noticed that if the user removes the screen when transitioning between images it doesn't work. But if the user taps on the screen while the image is on the screen (for 2 seconds), everything works fine.

Always on the main topic.

:( I am disconnected, it causes the program to crash due to memory.

- EDIT -

Finally, I decided to use the BOOL flag. But I think this is a bad solution because it should work without. Something weird happens when the animation is running, because it only works when the animation is not running.

This works for all cases:

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

}

      

Thanks for all.

+3


source to share


1 answer


change the arguments passed to both methods as shown



[self performSelector:@selector(SampleMethod) withObject:self afterDelay:delayTime];     
[NSObject cancelPreviousPerformRequestsWithTarget:self];       

      

+3


source







All Articles