2012年2月22日水曜日

NSOperationのdeallocが呼ばれなくてハマりました

ひさしぶりにメモリ関連でハマりました。
NSOperationのdeallocが呼び出されなくてメモリーリークしまクリスティ。
setCompletionBlock内でoperation自身を参照したのが原因のようです。「自分で自分のリテインカウントをインクリメントして保持」てきなことが起こっているのかな?

// オペレーションがqueueから削除された時の処理設定
 [anOperation setCompletionBlock:^{
  // delegateに通知
  if (_delegate) {
   [_delegate netWorkConnector:self requestOperationCompleted:_request];
  }
  
  // 保持しているrequestの解放
  [operations removeObject:anOperation];
  if ([operations count] <= 0) {
   [self.delegateOperationDictionary removeObjectForKey:pointerOfDelegate];
  }
  GNRLoggerDebug(@"-- operation  completed --");
 }];
 

operationのアドレス情報を別変数に入れることで解決しました。
// オペレーションがqueueから削除された時の処理設定
 NSNumber *p = [NSNumber numberWithInteger:(NSInteger)anOperation];
 [anOperation setCompletionBlock:^{
  // delegateに通知
  if (_delegate) {
   [_delegate netWorkConnector:self requestOperationCompleted:_request];
  }
  
  // 保持しているrequestの解放
  [operations removeObject:(id)[p integerValue]];
  if ([operations count] <= 0) {
   [self.delegateOperationDictionary removeObjectForKey:pointerOfDelegate];
  }
  GNRLoggerDebug(@"-- operation  completed --");
 }];
 

まぁ原因の根本はBlocksの知識がしょっぱいからに違いない。。。
このエントリーをはてなブックマークに追加

0 件のコメント :

コメントを投稿