iOS:KVO内存泄漏?

时间:2014-03-03 20:40:32

标签: ios objective-c memory-leaks key-value-observing

注意:我发布此信息作为其他可能遇到同一问题的开发人员的参考。

为什么我的代码存在内存泄漏:

@interface SPWKThing : NSObject
@property (strong, nonatomic) NSArray *things;
@end

@implementation SPWKThing {
    BOOL _isKVORegistered;
}

- (id)init
{
    self = [super init];
    if (self) {
        NSLog(@"initing SPWKThing");
        [self registerKVO];
    }
    return self;
}

- (void)didChangeValueForKey:(NSString *)key {
    if ([key isEqualToString:@"things"]) {
        NSLog(@"didChangeValueForKey: things have changed!");
    }
}

#pragma mark - KVO
- (void)registerKVO
{
    if (!_isKVORegistered) {
        NSLog(@"Registering KVO, and things is %@", _things);
        [self addObserver:self forKeyPath:@"things" options:0 context:NULL];
        _isKVORegistered = YES;
    }
}

- (void)unregisterKVO
{
    if (_isKVORegistered) {
        NSLog(@"Unregistering KVO");
        [self removeObserver:self forKeyPath:@"things"];
        _isKVORegistered = NO;
    }
}

- (void)dealloc
{
    NSLog(@"SPWKThing dealloc");
    [self unregisterKVO];
}

@end

@implementation SPWKViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self runDemo];
}

- (void)runDemo
{
    SPWKThing *thing = [[SPWKThing alloc] init];
    thing.things = @[@"one", @"two", @"three"];
    thing = nil;
}

@end

我的输出是:

initing SPWKThing
Registering KVO, and things is (null)
didChangeValueForKey: things have changed!
永远不会打电话给{p> dealloc?为什么?我在thing = nil的最后一行设置了runDemo

在此处查看演示项目:https://github.com/jfahrenkrug/KVOMemoryLeak

1 个答案:

答案 0 :(得分:3)

答案是:

永远不会覆盖didChangeValueForKey: (至少在没有调用super的情况下)。 documentation does not warn you about thishttps://github.com/jfahrenkrug/KVOMemoryLeak

请改用正确的方法observeValueForKeyPath:ofObject:change:context:

这个项目清楚地证明了这一点:{{3}}