2012-03-29 10 views
27

ARCを持つios5.0では、私のrootviewcontrollerに、アプリケーションデリゲートが保持するセキュリティマネージャオブジェクトのメソッドを呼び出します。その方法のIセットアップでNSTimerがセレクタを起動しない

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

以下のようにタイマーがしかし、これはセレクタすなわち発射することはありません。 updateModel:決して呼び出されません。何が間違っているのでしょうか? NStimerを使用せずにこれを行うことができるもう一つの効率的な方法はありますか?

答えて

10

あなたは少しタイマー変数と混じっているようです。

新しいタイマーを初期化しますが、実際には使用していません。初期化したタイマーを使用するか、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]; 
+0

申し訳ありません私はそれをやっている方法を反映するように編集しました。私はあなたが言及した第二の方法を使用しています...それはまだ動作していません。 – inforeqd

+20

2番目の方法が間違っています。タイマーを2回追加しようとしています。 'scheduledTimerWithTimeInterval:...'はすでにタイマーを追加しています。メインスレッドでこれを実行していることを確認してください。 –

+0

には、どのスレッドにタイマーが追加されているかを調べる手段がありますか?私はそれが私がそれを追加している主なスレッドだと思う... – inforeqd

5

をこの行は、いくつかの問題があります。

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

まず、必ずしも必要ではありません。 -scheduledTimerWithTimeInterval:...は既にタイマーをランループに追加しています。もう一度追加する必要はありません。

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

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

+0

投稿のミスについて申し訳ありません。私はそれをやっている方法を反映するように編集しました....それはまだ動作していません。アプリケーションデリゲートの使用に関するあなたのコメントについて私は、Webサービスレスポンスを解析した後に作成するモデルを用意しています。私はアプリケーションのすべてのビューのモデルを保持する必要があります。したがって、モデルをアプリケーション代理人が保持する必要があると思います。それ以外の場所では、すべてのビューを使用するためにどこに保管する必要があるのか​​分かりません。 – inforeqd

+1

モデルを作成するときにモデルをビューコントローラに渡すことも、モデルオブジェクトをシングルトンに配置することもできます。あなたはそれらをアプリケーションデリゲートに掛けるべきではありません。これは、コードの再利用を非常に困難にし、アプリケーションデリゲート(データを保存することと無関係に実行する独自の機能を持つ)を複雑にします。 –

8

私は同じ問題をキャッチし、私はそれを解決するために、メインキューにタイマーを発射:

[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"); 
    }); 
} 
105

も、スレッドの問題が考えられます。

[NSThread isMainThread] 

がfalseの場合は、次に起動このようなタイマー:

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

+1、ありがとう...これはトリックでした! – Joe

+1

ありがとう!スレッドの問題点を教えてください。 – JohnH

+4

タイマーは、メイン(UI)スレッドでのみ正しく実行されます。メインスレッド以外のスレッドでタイマーを起動しようとすると起動しません。 – tmanthey

関連する問題