2012-01-20 11 views
1

NSTimersを結合参照として使用するには?私は次のことを試してみた

しかし
- (void)setupTimer {  
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(doSomething) userInfo:nil repeats:YES]; 
    objc_setAssociatedObject(self, &key, timer, OBJC_ASSOCIATION_RETAIN); 
    [timer invalidate]; 
} 

- (void)doSomething { /* ... */ } 
- (void)afterDoingSomething { [objc_getAssociatedObject(self, &key) invalidate]; } 

、タイマーは(私はそれがそうすることを期待しませんでした。このコードは、ちょうど私に多くの権利を見ていない)ダニいない何らかの理由。それを作る方法はありますか...働くのですか?

答えて

5

タイマーを作成およびスケジューリングした直後に無効にしています。 documentationから

- (void)setupTimer {  
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(doSomething) userInfo:nil repeats:YES]; 
    objc_setAssociatedObject(self, &key, timer, OBJC_ASSOCIATION_RETAIN); 
} 

-setupTimer[timer invalidate];行を削除し

[無効]二度と発射から受信機を停止し、その実行ループから その除去を要求します。

このコードがカテゴリに含まれていると仮定して正しいですか?さもなければ、私はタイマーをそれに正規のインスタンス変数を使用するのではなく、関連するオブジェクトにする良い理由は考えられません。

+0

はい、そうです。私は私の連想参照内のタイマーを保持している場合、私はタイマーを処分しなかった場合私は漏れていないだろうか? – Matoe

+2

'-invalidate'はメモリ管理とは関係ありません。タイマーを解除して起動しないようにします。 'release'と同じことではありません。次に、 '-scheduledTimerWithTimeInterval:...'メソッドは自動解放されたインスタンスを返すので、解放する責任はありません。タイマーが終了したら、 '-afterDoingSomething'で連想参照を取り除くべきです。これを行うには、 'objc_setAssociatedObject()'をnilでもう一度呼び出します。連想参照関数はそれを行うため、タイマーでreleaseを呼び出す必要はありません。 ObjCのメモリ管理をレビューするのに良いかもしれない... –

0

タイマーを連想参照として設定することは問題ではないと思います。

  1. それは実際に(invalidateがそう)を開始する前に、あなたはあなたのタイマーを殺しています。

  2. お客様の- (void)doSomethingメソッドの署名は、- (void)doSomething: (NSTimer*)theTimerである必要があります。

  3. メモリがリークしている可能性があります。afterDoingSomethingobjc_setAssociatedObject(self, &key, nil, OBJC_ASSOCIATION_RETAIN);を書き込む必要があります。

1

あなたは間違っている必要があります。invalidatereleaseです。 objc_setAssociatedObjectは次の項目を設定するとreleaseとなります。

関連する問題