web-dev-qa-db-ja.com

NSTimerがセレクターを起動しない

ARCを使用するios5.0では、rootviewcontrollerで、アプリデリゲートによって保持されているセキュリティマネージャーオブジェクトのメソッドを呼び出します。その方法で私は以下のようにタイマーを設定しました

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
                                       selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

ただし、これはセレクターを起動しません。 updateModel:呼び出されることはありません。何が悪いのでしょうか? NStimerを使用せずにこれを行うことができる別のより効率的な方法はありますか?

30
inforeqd

タイマー変数と少し混同しているようです。

新しいタイマーを初期化しますが、実際には使用していません。初期化したタイマーを使用しますか、それともApplicationDelegate.timerを使用しますか?

考えられる2つの解決策を次に示します。

オプション1(ApplicationDelegateというタイトルのクラスインスタンスがあり、タイマープロパティがあると想定):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];

オプション2:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
13
sosborn

スレッドの問題である可能性もあります。

もし

[NSThread isMainThread]

falseの場合、次のようにタイマーを開始します。

dispatch_async(dispatch_get_main_queue(), ^{
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
    })
116
tmanthey

私は同じ問題をキャッチし、それを解決するためにメインキューでタイマーを起動します。

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
         [self loopUpUpdateStart];
}];

-(void)loopUpUpdateStart{
    dispatch_async(dispatch_get_main_queue(), ^{

        _loopTimerForUpRevision = 
          NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev
                                          target: self
                                        selector: @selector(myCoolMethod)
                                        userInfo: nil
                                         repeats: YES];
        TRACE(@"Start Up updates");
    });
}
8
WINSergey

この行にはいくつかの問題があります:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

まず、それはまったく必要ありません。 -scheduledTimerWithTimeInterval:...は既にタイマーを実行ループに追加しています。再度追加する必要はありません。

次に、ローカル変数timerは、プロパティApplicationDelegate.timerとは無関係です(この時点では、おそらくnilです)。

アプリケーションデリゲートとやり取りしすぎて、ApplicationDelegate(グローバル?マクロ?)と呼ばれるものを作成した場合は、やりすぎです。アプリケーションデリゲートは、アプリケーションのデリゲートです。アプリケーションの起動と停止、およびシステムイベントへの応答を支援します。アプリケーションデリゲートは、グローバル変数を格納する場所ではありません。タイマーは、絶対に別のオブジェクトからフェッチするものではありません。

7
Rob Napier