LeoMaer LeoMaer - 6 months ago 25
iOS Question

iOS:KVC,when I exit of my app,there comes a issue with KVC

I use

kvc
in my code.

[self addObserver:self forKeyPath:@"type" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
[self addObserver:self forKeyPath:@"location" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];


And I also take the function here:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {

if ([keyPath isEqualToString:@"location"] || [keyPath isEqualToString:@"type"]) {

// refresh data
if (self.currentTableView == _sellTableView) {

[self addSellDataSourceWithFlag:1];
}else {
[self addBuyDataSourceWithFlag:1];
}
}
}


In dealloc, I remove them.

- (void)dealloc {

[self removeObserver:self forKeyPath:@"location"];
[self removeObserver:self forKeyPath:@"type"];
}


But, when I logout my app:

// exit
- (IBAction)exitButtonPress:(UIButton *)sender {


self.navigationController.navigationBar.hidden = YES;


self.tabBarController.tabBar.hidden = YES;


[[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"user_isLogin"];
[[NSUserDefaults standardUserDefaults] synchronize];


[self.tabBarController dismissViewControllerAnimated:YES completion:^{

[self.tabBarController setSelectedIndex:0];
}];

}


There become an issue, with the
All Exceptions
, it appears the row:

[self removeObserver:self forKeyPath:@"location"];


The issue info is below:

libc++abi.dylib: terminate_handler unexpectedly threw an exception


And when I
bt
:

(lldb) bt
* thread #1: tid = 0x387c7, 0x000000010a6dbf06 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x000000010a6dbf06 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x000000010a6a34ec libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x000000010a43dcec libsystem_c.dylib`abort + 129
frame #3: 0x000000010a23c051 libc++abi.dylib`abort_message + 257
frame #4: 0x000000010a25f292 libc++abi.dylib`std::__terminate(void (*)()) + 44
frame #5: 0x000000010a25eef9 libc++abi.dylib`__cxa_rethrow + 99
frame #6: 0x0000000107b3cf5e libobjc.A.dylib`objc_exception_rethrow + 40
frame #7: 0x000000010831e1b4 CoreFoundation`CFRunLoopRunSpecific + 676
frame #8: 0x000000010a83ead2 GraphicsServices`GSEventRunModal + 161
frame #9: 0x0000000108cc3f09 UIKit`UIApplicationMain + 171
* frame #10: 0x00000001047d5b8f E农通`main(argc=1, argv=0x00007fff5b562638) + 111 at main.m:14
frame #11: 0x000000010a39792d libdyld.dylib`start + 1
frame #12: 0x000000010a39792d libdyld.dylib`start + 1


Somebody know this issue with
kvc
? I have no solution with this, thanks for your attention.

Answer

LeoMaer,

You might be trying to remove the observer even before you have added it. So the solution is to make sure that you have added it before removing the observer.

Try adding your observer either in init or viewDidLoad of your class and then remove it in dealloc.

On the other hand if you have some specific requirement and you have to add it based on condition or something like that use this to avoid crash.

This will remove observer if added else exception will be catched and wont crash

@try{
   [self removeObserver:self forKeyPath:@"location"];
}@catch(id anException){
   //catch the exception
}