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