6

遅延後に実行するように設定された performSelector を持つビューがある場合:

[self performSelector:@selector(generateBall) withObject:NULL afterDelay:1.5];

...しかし、セレクターが起動する前にそのビューを削除すると (たとえば、ユーザーの操作が原因で)、アプリがクラッシュします。

そのビューの dealloc メソッドで遅延セレクターを強制終了する方法はありますか?

編集:

私は両方を試しました:

[[NSRunLoop mainRunLoop] cancelPerformSelector:theBall target:self argument:nil];

[[NSRunLoop currentRunLoop] cancelPerformSelector:theBall target:self argument:nil];

両方が機能している間 (新しいビューをロードできます)、前のビューをロードすると灰色の画面が表示されます。

リストされている Apple ドキュメント以外の cancelPerformSelector に関するチュートリアルやその他の情報を見つけることができませんでした。スレッドと実行ループに関するドキュメントは非常に複雑なようです (ほとんどの場合、実際のコード サンプルがリストされていないためです。何が起こっているのかを理解するのが簡単になります)。

4

3 に答える 3

15

私はperformSelector:afterDelayを使用しているため、以前に要求されたが起動されていない機能を適切に「強制終了」できる唯一の方法は、次を使用することです。

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:theBall object:nil];

次のコードサンプルは、これがどのように機能するかを示しています( "select"という名前の新しいViewテンプレートXCodeプロジェクトを作成し、selectViewController.hファイルをこれに置き換えます)。

#import "selectViewController.h"

@implementation selectViewController

UILabel *lblNum;
UIButton *btnStart, *btnStop;
int x;

- (void) incNum {
    x++;
    lblNum.text = [NSString stringWithFormat:@"%i", x];
    [self performSelector:@selector(incNum) withObject:NULL afterDelay:1.0];
}

- (void) stopCounter {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(incNum) object:NULL];
}

- (void)viewDidLoad {
    x = 0;

    lblNum = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    lblNum.textAlignment = UITextAlignmentCenter;
    [self.view addSubview:lblNum];

    btnStart = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btnStart.frame = CGRectMake(40, 270, 240, 30);
    [btnStart setTitle:@"start" forState:UIControlStateNormal];
    [btnStart addTarget:self action:@selector(incNum) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnStart];

    btnStop = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btnStop.frame = CGRectMake(40, 310, 240, 30);
    [btnStop setTitle:@"stop" forState:UIControlStateNormal];
    [btnStop addTarget:self action:@selector(stopCounter) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnStop];

    [self performSelector:@selector(incNum) withObject:NULL afterDelay:1.0];
    [super viewDidLoad];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}

- (void)dealloc {
    [lblNum release];
    [super dealloc];
}

@end
于 2009-07-15T21:34:51.670 に答える
5

-cancelPerformSelectorsWithTarget:

また

-cancelPerformSelector:target:argument:

于 2009-07-14T03:14:35.690 に答える
3

これがうまく機能することがわかりました:

[NSObject cancelPreviousPerformRequestsWithTarget:self];
于 2014-02-25T19:40:56.520 に答える