這い寄る混沌

今度はテスト時にこんなログが飛ぶようになった。

2012-05-29 20:02:46.675 HogeApp[409:f803] An instance 0x6e20250 of class HogeTask was deallocated while key value observers were still registered with it. 
Observation info was leaked, and may even become mistakenly attached to some other object. 
Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x6c24870> (
<NSKeyValueObservance 0x6c250a0: Observer: 0x6e20270, Key path:
isShowingHUDinProgress, Options: <New: YES, Old: NO, Prior: NO>
Context: 0x4c14c, Property: 0x6e21430>
)

前半を要約すると

HogeTaskクラスのインスタンスがKVO(Key Value Observing)通知オブジェクトがまだ登録されているにも関わらずメモリ割り当てが解除されてしまった。監視情報はリークするか、誤って他のオブジェクトに関連づけられるだろう。云々〜

ご丁寧にもKVO機構が登録されているオブジェクトが消されたことを検出して警告を出してくれているようだ。

KVO通知を行っている場所は判っている。

BBAsyncTask.m (抜粋)
@implementation BBAsyncTask
{
   __strong _MethodProxy* _proxy;
}
@synthesize isShowingHUDinProgress;
@synthesize progressHUD;
- (id)init
{
   self = [super init];
   _proxy = [[_MethodProxy alloc] initWithTarget:self];

   [self addObserver:self forKeyPath:@"isShowingHUDinProgress" selector:@selector(didShowingHUDinProgressChanged:ofObject:change:context:) userInfo:nil options:NSKeyValueObservingOptionNew];

   [self setIsShowingHUDinProgress:YES];

   return (BBAsyncTask*)_proxy;
}
- (void)didShowingHUDinProgressChanged:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
   if ( _proxy )
   {
       [_proxy setIsShowingHUDinProgress:[self isShowingHUDinProgress]];
   }
}
- (void)dealloc
{
   [self removeObserver:self forKeyPath:@"isShowingHUDinProgress" selector:@selector(didShowingHUDinProgressChanged:ofObject:change:context:)];
   _proxy = nil;
}
@end

このクラスにはBBAsyncTaskProtocolのexecuteメソッドに割り込んで前後処理を実行するためのNSProxyの継承クラスを保持しており、そのプロパティをBBAsyncTaskクラスから操作するのにKVOを使用している。

イニシャライザでKVOを登録し、dealloc時に登録を解除しているので問題は無いはずなのだが... .... ...

とここまで書いて原因がほぼ特定できてしまった。 これは恥ずかしい。