Reputation: 169
So I have a class, CustomCell : UITableViewCell
with a single addObserver:forKeyPath:options:context:
method, called in -awakeFromNib
, and a single removeObserver:forKeyPath:context:
method, called 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
}
I get the following log, after loading the view with these cells, then backing out again (triggering the 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)
I've double-checked (ctrl+f) that nowhere else are these methods called. So it seems that for any instance, there is precisely one addObserver
(with unique context) and precisely one removeObserver
(with that context)
Upvotes: 1
Views: 2025
Reputation: 169
Apologies all
Have just spotted my typo:
[self removeObserver:self
forKeyPath:@"currentLocation"
context:MyClassKVOContext];
should be
[[RA_LocationSingleton locationSingleton] removeObserver:self
forKeyPath:@"currentLocation"
context:MyClassKVOContext];
Upvotes: 2