所以我有一个类,CustomCell : UITableViewCell
有一个addObserver:forKeyPath:options:context:
方法,称为 in -awakeFromNib
,和一个removeObserver:forKeyPath:context:
方法,称为 in -dealloc
。
CustomCell.m
static void * const MyClassKVOContext = (void*)&MyClassKVOContext; // unique context
-(void)awakeFromNib
{
[super awakeFromNib];
[self registerAsLocationListener];
}
-(void)registerAsLocationListener
{
if ([self.reuseIdentifier isEqualToString:@"locationcell1"])
{
[[RA_LocationSingleton locationSingleton]
addObserver:self
forKeyPath:@"currentLocation"
options:NSKeyValueObservingOptionNew
context:MyClassKVOContext];
NSLog(@"Registered for currentLocation");
NSLog(@"self.description: %@", [self description]);
}
}
-(void)dealloc
{
if ([self.reuseIdentifier isEqualToString:@"locationcell1"])
{
NSLog(@"Attempting to deregister");
NSlog(@"self.description: %@", [self description]);
[self removeObserver:self
forKeyPath:@"currentLocation"
context:MyClassKVOContext];
}
// [super dealloc]; called automatically, using ARC
}
在使用这些单元格加载视图后,我得到以下日志,然后再次退出(触发 dealloc)
// load view
2014-09-01 14:27:33.704 Rally[2931:60b] Registered for currentLocation
2014-09-01 14:27:33.705 Rally[2931:60b] self.description: <CustomCell: 0x9afa570; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = RM+BM; layer = <CALayer: 0x9afa710>>
// exit from view
2014-09-01 14:27:40.867 Rally[2931:60b] Attempting to deregister
2014-09-01 14:27:40.868 Rally[2931:60b] self.description: <CustomCell: 0x9afa570; baseClass = UITableViewCell; frame = (0 231; 320 44); autoresize = W; layer = <CALayer: 0x9afa710>>
2014-09-01 14:27:40.870 Rally[2931:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <CustomCell 0x9afa570> for the key path "currentLocation" from <CustomCell 0x9afa570> because it is not registered as an observer.'
*** First throw call stack:
(
0 CoreFoundation 0x026761e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x023f58e5 objc_exception_throw + 44
2 CoreFoundation 0x02675fbb +[NSException raise:format:] + 139
3 Foundation 0x0204346d -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 538
4 Foundation 0x020431f4 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 105
5 Foundation 0x02043118 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:context:] + 172
6 Rally 0x00005ac1 -[CustomCell dealloc] + 353
7 UIKit 0x01107b94 -[UIView release] + 89
8 CoreFoundation 0x025f7bf0 CFRelease + 272
9 CoreFoundation 0x0261716e -[__NSArrayM dealloc] + 142
10 libobjc.A.dylib 0x02406692 _ZN11objc_object17sidetable_releaseEb + 268
11 libobjc.A.dylib 0x02405e81 objc_release + 49
12 libobjc.A.dylib 0x02406ce7 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 537
13 CoreFoundation 0x02617878 _CFAutoreleasePoolPop + 24
14 CoreFoundation 0x0261c5d3 __CFRunLoopRun + 1971
15 CoreFoundation 0x0261b9d3 CFRunLoopRunSpecific + 467
16 CoreFoundation 0x0261b7eb CFRunLoopRunInMode + 123
17 GraphicsServices 0x036f85ee GSEventRunModal + 192
18 GraphicsServices 0x036f842b GSEventRun + 104
19 UIKit 0x010b5f9b UIApplicationMain + 1225
20 Rally 0x00006a6d main + 141
21 libdyld.dylib 0x02ef6701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
我已经仔细检查(ctrl+f),这些方法在其他任何地方都没有被调用。因此,对于任何情况,似乎都有一个addObserver
(具有独特的上下文)和一个removeObserver
(具有该上下文)