照KVO所说的去做。观察,采取相应行动,并在需要时手动发出钥匙信号。这样,您当然可以知道对象何时被释放。当您从 Object 中 removeObserver 并且它已经被释放时,方法调用将作用于 nil ,这不会造成任何伤害,或者您的观察对象仍然持有引用,在这种情况下您仍然可以采取相应的行动。
使用 ARC,这不是问题,也是最大的好处之一。
自己测试一下。。
// public header.
@interface ObjectToBeObserved : NSObject
@end
// declare in private header
// because you dont want to allow triggering from outside
@interface ObjectToBeObserved : NSObject
// use some artificial property to make it easy signalling manually.
@property (nonatomic) BOOL willDealloc;
@end
@implementation ObjectToBeObserved
-(void)dealloc {
[self willChangeValueForKey:@"willDealloc"];
[self didChangeValueForKey:@"willDealloc"];
}
@end
在您的观察者方面,您只需执行经典的 KVO 设计模式..
void* objectDeallocatedContext = & objectDeallocatedContext;
@implementation ObservingObject {
// easy to see you could even make a protocol out of the design pattern
// that way you could guarantee your delegate has such property to observe
__weak ObjectToBeObserved *delegate;
}
-(instancetype)initWithObservableDelegate:(ObjectToBeObserved*)observable {
if (!(self=[super init])) return nil;
delegate = observable;
// see i use observe old value here..
if (delegate!=nil)
[delegate addObserver:self forKeyPath:@"willDealloc" options:(NSKeyValueObservingOptionOld) context:objectDeallocatedContext];
return self;
}
-(void)dealloc {
if (delegate!=nil)
[delegate removeObserver:self forKeyPath:@"willDealloc" context: objectDeallocatedContext];
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (context==objectDeallocatedContext) {
NSLog(@"the observed object deallocated");
// in theory you hold still a weak reference here
// which should be nil after this KVO signal arrived.
// the object in the signal therefore might not be valid anymore,
// which is what you want when observing deallocation.
}
}
@end
KVO 是一种信号模式,而不是一种知道信号对象是否仍然有效的方法。但是当物体消失时它不会发出任何信号,那些当你能收到信号时你就很好了。因为我选择NSKeyValueObservingOptionOld
用 a 观察值void* context
,所以它甚至会在对象人工“willDealloc”属性设置之前发出信号(嗯,甚至没有设置)。KVO 可以在没有有效对象的情况下到达,但仍有要比较的上下文。你只需要ping