1

所以我有一个类,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(具有该上下文)

4

1 回答 1

2

向所有人道歉

刚刚发现我的错字:

[self removeObserver:self
           forKeyPath:@"currentLocation"
              context:MyClassKVOContext];

应该

[[RA_LocationSingleton locationSingleton] removeObserver:self
                                              forKeyPath:@"currentLocation"
                                                 context:MyClassKVOContext];
于 2014-09-01T14:02:07.500 回答