cancelPreviousPerformRequestsWithTarget не работает - PullRequest
3 голосов
/ 09 марта 2012

Я использую в классе этот метод для запуска действия:

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

Что мне не хватает?

Спасибо.

--- EDIT ---

Чтобы узнать, используется ли основная тема, я использую:

-(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, вызывается с помощью executeOnMainThread:

Спасибо.

- EDIT ---

Я изменил метод с предложениями, но все еще не работает:

-(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 секунд), все работает нормально.

Всегда в основной теме.

:( Я перестал работать, это приводит к сбою программы из-за памяти.

- EDIT -

Наконец я решил использовать флаг 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];

}

Спасибо за все.

1 Ответ

3 голосов
/ 01 октября 2013

изменить аргументы, передаваемые обоим методам, как показано,

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