3

奇妙なリークに直面しています。Car次のクラスのオブジェクトは決して割り当て解除されません。

ただし、インスタンス変数を取り除き、_unsafe_self代わりにメソッド内で変数を宣言 (および以前のように代入)initすると、リークはなくなります。

何が原因でしょうか? __weakインスタンス変数であろうとなかろうと、いつも弱いと思っていました。

@interface Car : NSObject
@end

@implementation Car {
  id _obs;
  __weak Car *_unsafe_self;
}

- (id)init {
  if (!(self = [super init]))
    return nil;

  _unsafe_self = self;

  _obs = [[NSNotificationCenter defaultCenter]
          addObserverForName:NSWindowDidMoveNotification
          object:nil
          queue:[NSOperationQueue mainQueue]
          usingBlock:^(NSNotification *note) {
              NSLog(@"hello %@", _unsafe_self);
            }];

  return self;
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:_obs];
}
@end
4

1 に答える 1

9

_unsafe_selfは と同じself->_unsafe_selfであるため、 のブロック

_obs = [[NSNotificationCenter defaultCenter]
          addObserverForName:NSWindowDidMoveNotification
          object:nil
          queue:[NSOperationQueue mainQueue]
          usingBlock:^(NSNotification *note) {
              NSLog(@"hello %@", _unsafe_self);
            }];

をキャプチャしself、割り当て解除を妨げる保持サイクルを引き起こしselfます。

これにより保持サイクルは発生しません。

__weak Car *weakSelf = self;
_obs = [[NSNotificationCenter defaultCenter]
        addObserverForName:NSWindowDidMoveNotification
        object:nil
        queue:[NSOperationQueue mainQueue]
        usingBlock:^(NSNotification *note) {
            NSLog(@"hello %@", weakSelf);
        }];

プロパティself.unsafe_selfを使用すると、コード内でこれがより明確になりますが、「プロパティと ivar」の Q&A はすでに十分すぎるほどあります :-)

于 2013-04-22T19:29:08.070 に答える