iOS: KVC,当我退出我的应用程序时,KVC 出现问题
iOS: KVC, when I exit of my app, there comes a issue with KVC
我在我的代码中使用 kvc
。
[self addObserver:self forKeyPath:@"type" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
[self addObserver:self forKeyPath:@"location" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
而且我这里也取了函数:
- (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];
}
}
}
在 dealloc 中,我删除了它们。
- (void)dealloc {
[self removeObserver:self forKeyPath:@"location"];
[self removeObserver:self forKeyPath:@"type"];
}
但是,当我注销我的应用程序时:
// 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];
}];
}
All Exceptions
出现问题,显示行:
[self removeObserver:self forKeyPath:@"location"];
问题信息如下:
libc++abi.dylib: terminate_handler unexpectedly threw an exception
而当我 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
如何用 kvc
解决这个问题?
里奥马尔,
您可能在添加观察者之前就试图将其移除。所以解决方案是确保在删除观察者之前已经添加了它。
尝试在 class 的 init 或 viewDidLoad 中添加观察者,然后在 dealloc 中将其删除。
另一方面,如果您有一些特定的要求并且必须根据条件或类似的东西添加它,请使用它来避免崩溃。
如果添加,这将删除观察器,否则将捕获异常并且不会崩溃
@try{
[self removeObserver:self forKeyPath:@"location"];
}@catch(id anException){
//catch the exception
}
为了解决这个问题,我有一个解决方案。
拿个@属性 NSMutableArray *observe_arr;
如果是行政人员 [self addObserver:self forKeyPath:@"observeName" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
将 observeName
添加到 observe_arr
。
在dealloc中:
- (void)dealloc {
while (self.observe_arr.firstObject) {
[self removeObserver:self forKeyPath:self.observe_arr.firstObject];
}
}
顺便说一下,非常感谢 Sandeep Bhandari 的帮助。
我在我的代码中使用 kvc
。
[self addObserver:self forKeyPath:@"type" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
[self addObserver:self forKeyPath:@"location" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
而且我这里也取了函数:
- (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];
}
}
}
在 dealloc 中,我删除了它们。
- (void)dealloc {
[self removeObserver:self forKeyPath:@"location"];
[self removeObserver:self forKeyPath:@"type"];
}
但是,当我注销我的应用程序时:
// 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];
}];
}
All Exceptions
出现问题,显示行:
[self removeObserver:self forKeyPath:@"location"];
问题信息如下:
libc++abi.dylib: terminate_handler unexpectedly threw an exception
而当我 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
如何用 kvc
解决这个问题?
里奥马尔,
您可能在添加观察者之前就试图将其移除。所以解决方案是确保在删除观察者之前已经添加了它。
尝试在 class 的 init 或 viewDidLoad 中添加观察者,然后在 dealloc 中将其删除。
另一方面,如果您有一些特定的要求并且必须根据条件或类似的东西添加它,请使用它来避免崩溃。
如果添加,这将删除观察器,否则将捕获异常并且不会崩溃
@try{
[self removeObserver:self forKeyPath:@"location"];
}@catch(id anException){
//catch the exception
}
为了解决这个问题,我有一个解决方案。
拿个@属性 NSMutableArray *observe_arr;
如果是行政人员 [self addObserver:self forKeyPath:@"observeName" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
将 observeName
添加到 observe_arr
。
在dealloc中:
- (void)dealloc {
while (self.observe_arr.firstObject) {
[self removeObserver:self forKeyPath:self.observe_arr.firstObject];
}
}
顺便说一下,非常感谢 Sandeep Bhandari 的帮助。