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を使用せずにこれを行うことができる別のより効率的な方法はありますか?
タイマー変数と少し混同しているようです。
新しいタイマーを初期化しますが、実際には使用していません。初期化したタイマーを使用しますか、それとも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];
スレッドの問題である可能性もあります。
もし
[NSThread isMainThread]
falseの場合、次のようにタイマーを開始します。
dispatch_async(dispatch_get_main_queue(), ^{
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
})
私は同じ問題をキャッチし、それを解決するためにメインキューでタイマーを起動します。
[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");
});
}
この行にはいくつかの問題があります:
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes];
まず、それはまったく必要ありません。 -scheduledTimerWithTimeInterval:...
は既にタイマーを実行ループに追加しています。再度追加する必要はありません。
次に、ローカル変数timer
は、プロパティApplicationDelegate.timer
とは無関係です(この時点では、おそらくnil
です)。
アプリケーションデリゲートとやり取りしすぎて、ApplicationDelegate
(グローバル?マクロ?)と呼ばれるものを作成した場合は、やりすぎです。アプリケーションデリゲートは、アプリケーションのデリゲートです。アプリケーションの起動と停止、およびシステムイベントへの応答を支援します。アプリケーションデリゲートは、グローバル変数を格納する場所ではありません。タイマーは、絶対に別のオブジェクトからフェッチするものではありません。