我面临一个奇怪的泄漏。以下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
_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
将使这在代码中更明显,但是已经有足够多的"property vs ivar"(如:-)