如何从弱财产中清除KVO?
我有一个视图(我们称之为视图A),它的超级视图(视图B)具有weak
属性。 查看一个KVO的超级视图,查看B.因为视图A对视图B的引用是一个弱属性(为了防止保留周期),我怎样才能删除观察者(A观察B)? 查看A的视图B的引用在我有机会删除它之前没有被删除。
因为视图控制器有一个强烈的参考A.这里是泄漏的日志消息:
An instance 0x9ac5200 of class UITableView was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info: <NSKeyValueObservationInfo 0x8660360> ( <NSKeyValueObservance 0x8660320: Observer: 0x8660020, Key path: contentOffset, Options: <New: YES, Old: NO, Prior: NO> Context: 0x8660020, Property: 0x864ac80> )
B是一个UITableView。 在NSKVODeallocateBreak
处设置断点NSKVODeallocateBreak
产生无用的结果。
在A的removeFromSuperview
,我尝试删除观察者,但A对B的引用已经是nil
。
切换到unsafe_unretained
并且更手动地执行或者在视图控制器的dealloc
调用[A removeFromSuperview]
来解决这个问题。 我想知道如何解决这个使用weak
财产,虽然。
以下是相关的代码: https : //gist.github.com/2822776
我发现这种情况下特别需要的任何代码实际上是不必要的,因为可以自动移除。
随着ARC的推出,苹果公司应该提供自动移除观察者来修复这种情况,但不幸的是他们没有。 但我已经做了我自己的类别,增加了这个缺乏的function: https : //github.com/krzysztofzablocki/SFObservers我已经解释了我是如何pipe理我的博客上: http : //www.merowing.info/2012/ 03 /自动去除-的-nsnotificationcenter -或KVO-观察员/
如果你看看我的解决scheme,你会注意到,即使其中一个方法调用了其他方法,也能确保原始代码被调用,所以即使苹果改变了它的内部行为,这个类仍然可以正常工作:)
你可以定义一个明确的弱引用超视图的属性,然后用@"propertyReferringSuperview.propertyOfSuperview"
的关键path观察self
? 当你得到一个KVO通知,你检查self.propertyReferringSuperview == nil
并停止观察@"propertyReferringSuperview.propertyOfSuperview"
。
您可以使用willMoveToSuperview:
属性并实现willMoveToSuperview:
添加/删除KVO观察值,而不是添加弱属性。
- (void)willMoveToSuperview:(UIView *)newSuperview { [self.superview removeObserver:self forKeyPath:@"contentOffset" context:context]; [newSuperview addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:context]; [super willMoveToSuperview:newSuperview]; // optional as default implementation does nothing }