私は一定の間隔(例えば、1分に1回)でメソッドを実行する必要のあるクラスを持っています。しかし、私はこれがターゲットのライフサイクルに影響を及ぼさないようにします。言い換えれば、待っている間にターゲットを保持したくないということです。このソリューションは、メインスレッドでのみ呼び出されるため、スレッドセーフである必要はありません。今の私の解決策は、クラスがまだ機能しているかどうかを示すためにプロキシを使います。プロキシは、クラスのライフサイクルに結びついていません。ターゲットを保持せずにメソッド呼び出しを遅らせます。
//BCDeathTag is the proxy for indicating the objects state
@interface BCDeathTag : NSObject
@property(readwrite, nonatomic, assign) BOOL isDead;
@end
@implementation BCDeathTag
@synthesize isDead = _isDead;
@end
//BCInterestingClass is where the interesting stuff happens
@interface BCInterestingClass : NSObject
@property(readonly, nonatomic) BCDeathTag *deathTag;
-(void)scheduleConsistencyCheck;
-(void)performConsistencyCheck;
...
@end
@implementation BCInterestingClass
@synthesize deathTag = _deathTag;
-(id)init
{
self = [super init];
if (self != nil)
{
_deathTag = [BCDeathTag new];
}
return self;
}
-(void)dealloc
{
_deathTag.isDead = YES;
[_deathTag release];
[super dealloc];
}
-(void)scheduleConsistencyCheck
{
__block BCInterestingClass* me = self; //prevent the block from retaining self
BCDeathTag *deathTag = self.deathTag; //but do retain the deathTag
double delayInSeconds = 60;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
if (deathTag.isDead == NO)
{
[me performConsistencyCheck];
}
});
}
-(void)performConsistencyCheck
{
//Do work here
//...
[self scheduleConsistencyCheck]; //repeat the check
}
@end
BCDeathTag
がNSLock
に置き換えることができますが、NSLock
は、より高価になるととして明確に示すものではありませつもりでしょう:ここではコードです。
これは完全な解決策ですか? Cocoaの標準パターンや既存のクラス/機能を見落としていませんか?