2013-04-22 61 views
3

我正面临一个奇怪的泄漏。以下Car类的对象永远不会被释放。为什么此代码在ARC下泄漏? (一个__weak实例变量)

但是,如果我摆脱实例变量_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 

回答

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将使这个代码更明显,但已经有够多了“财产VS伊娃” Q &作为:-)

相关问题