注意: 我发布这篇文章是为了其他可能遇到同样问题的开发人员提供参考。
为什么我在使用这段代码时会出现内存泄漏:
@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!
dealloc
没有被调用?为什么?我在 runDemo
的最后一行设置了 thing = nil
!
setThings
变化的代码放在某个地方即可...除非这个问题是用来讨论的练习... - Tim ReddyunregisterKVO
中设置断点会发生什么?在您的实现中使用BOOL
是我以前从未做过的...通常我会在.m
文件中使用类扩展来放置私有iVars...(即:@interface SPWKThing() {BOOL _isKVORegistered;} @end
) - Tim Reddysuper
的情况下重写didChangeValueForKey:
会导致内存泄漏。关于BOOL
:https://dev59.com/Smox5IYBdhLWcg3w95E9#8853683 - Johannes Fahrenkrugdealloc
会被调用吗? - MerlevedeaddObserver:forKeyPath:options:context:
,那么对象将被正确释放。 - Johannes Fahrenkrug