2011-10-21 14 views
1

クラスMotionStreakのivarを持つクラスTouchInfoがあります。親オブジェクトがdeallocされた後にivarのリリースが遅れる

@interface TouchInfo : NSObject { 
    MotionStreak *streak; 
} 
... 
@end 

このクラスは、基本的にタッチイベントを処理し、タッチに続くモーションスジを描画します。ユーザーが指を離したときに特定のタッチに関連付けられているTouchInfoのインスタンスを解放したいが、フェードアウトする前にモーションスジークを0.5〜1.0秒間残しておきたいので、deallocstreak ivarをリリースすることはできない方法はTouchInfoクラスです。

私は次のようにカスタムのTimerクラスを使用して、streak IVARの放出を遅延するためにタイマーを使用しています:

- (void)dealloc { 
    [self timedReleaseStreak]; 
    [super dealloc]; 
} 

- (void)timedReleaseStreak { 
    [streak fadeoutWithDelay:1.0]; 
    [[TimerHandler sharedTimer] object:streak action:@selector(release) delay:1.0]; 
} 

これまでのところ、それは任意のクラッシュせずに動作します。しかし、私はこれを間違ってやっているのかどうか、またそれを行うためのより良い方法と推奨される方法があるのだろうかと思います。ご意見をお聞かせください。

p/s:ARCに関するアドバイスはありません。 P

+0

私は他のオブジェクト(タッチされたビュー)に責任を与えることはおそらくより安全だろうと思いましたか? – jbat100

答えて

0

ブロックはコピーを取得したときに参照するオブジェクトを保持するので、それらを使ってアニメーションを実装できます。これにより、ブロックの割り当てが解除されるまでオブジェクトの割り当てが解除されなくなります。

ここでは、+[UIView animateWithDuration:animations:completion:]を使用してビューをフェードアウトし、ビュー階層から削除する例を示します。後でコンプリートブロックを使用するためには、それをヒープにコピーする必要があり、結果としてビューが保持されます。私はローカル変数にstreak IVARをコピーし、ブロック内のその使用

- (void)dealloc { 
    UIView *localStreak = streak; 
    [UIView animateWithDuration:1.0 animations:^ { 
     localStreak.alpha = 0.0; 
    } completion:^ (BOOL finished) { 
     [localStreak removeFromSuperview]; 
    }]; 
    [streak release]; 
    [super dealloc]; 
} 

注意。 ivarを直接使用しようとすると、代わりにselfが保持されます。これは、すでに割り振り解除プロセスを開始しているために機能しません。

関連する問題