web-dev-qa-db-ja.com

NSTimer timerWithTimeInterval:機能していません

プロジェクトに実装する前に、タイマー付きのテストアプリケーションを作成しました。タイマーを使うのは初めてでした。しかし、問題は[NSTimer timerWithTimeInterval: target: selector: userInfo: repeats: ];を使用してタイマーを実装したときに機能しません。これが私のコード、インターフェイスです:

@interface uialertViewController : UIViewController
{

    NSTimer *timer;
}

-(void)displayAlert;
-(void)hideandview;
@end

実装:

@implementation uialertViewController
- (void)viewDidLoad {

    [self displayAlert];
    [super viewDidLoad];
}


-(void)displayAlert{

    timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(hideandview) userInfo:nil repeats:NO];

    alert = [[UIAlertView alloc] initWithTitle:@"testing" message:@"hi hi hi" delegate:nil cancelButtonTitle:@"continue" otherButtonTitles:nil];
    [alert show];




    [alert release];
    alert = nil;

}

-(void)hideandview{

    NSLog(@"triggered");

    [alert dismissWithClickedButtonIndex:0 animated:YES];

    [alert release];

    [self displayAlert];
}

@end

Then I Changed[NSTimer timerWithTimeInterval: target: selector: userInfo: repeats: ];with[NSTimer scheduledTimerWithTimeInterval: target: selector:userInfo: repeats: ];、It is workingtimerWithTimeInterval:の問題は何でしたか?私の最初の実装で何かを見逃していますか?前もって感謝します。

30
Midhun MP

scheduledTimerWithTimeInterval:invocation:repeats:およびscheduledTimerWithTimeInterval:target:selector:userInfo:repeats:NSRunLoopに自動的に追加されるタイマーを作成します。つまり、自分で追加する必要はありません。それらをNSRunLoopに追加すると、起動します。

timerWithTimeInterval:invocation:repeats:およびtimerWithTimeInterval:target:selector:userInfo:repeats:、次のようなコードを使用して、実行ループにタイマーを手動で追加する必要があります。

[[NSRunLoop mainRunLoop] addTimer:repeatingTimer forMode:NSDefaultRunLoopMode];

ここでの他の回答は、fireを自分で呼び出す必要があることを示唆しています。タイマーは実行ループに置かれるとすぐに呼び出されます。

119
Joseph Humfrey

また、メインスレッドに必ずタイマーを追加することもできます。

assert(Thread.isMainThread)
let timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(YourSelector), userInfo: nil, repeats: true)
2

以前の回答として、メインスレッドのスケジュールを示しましたが、assertを使用するのではなく、メインスレッドに配置します。

@objc func update() {
    ...
}

DispatchQueue.main.async {
            self.timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
        }

そして、非同期が望ましくない場合は、これを試してください:

let schedule = {
            self.timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
        }

        if Thread.isMainThread {
            schedule()
        }
        else {
            DispatchQueue.main.sync {
                schedule()
            }
        }
1
Joe Pagliaro

2つの違いは、timerWithTimeIntervalメソッドがまだ起動されていないNSTimerオブジェクトを返すことです。タイマーを起動するには、[timer fire];を使用する必要があります。一方、scheduledTimerWithTimeIntervalは、既に起動されているNSTimerを返します。

したがって、最初の実装では[timer fire];がありませんでした

1
Chance Hudson