2016-05-31 1 views
0

코드에 kvc을 사용합니다.iOS : 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"]; 
} 

그러나이 : ​​

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

문제의 정보는 다음과 같습니다 :

// 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와 함께, 그것은 행이 표시 될

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

그리고 때 bt I :

(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이 문제를 알아? 나는 이것에 대한 해결책이 없으니주의 해 주셔서 감사합니다.

+0

KVC 대신 KVO (Key-Value Observing)를 의미 했습니까? – Andriy

+0

이 관찰을하는 수업은 무엇입니까? 또한 stacktrace가'removeObserver :'문과 일치하지 않습니다 ... – trojanfoe

+0

그리고 KVO를 사용하여 자신의 변경 사항을 모니터링하는 것은 매우 나쁜 생각입니다. 왜 당신은'type'과'location' 메소드를 오버라이드 할 수없고, 슈퍼 구현을 호출하고 데이터를 리프레시 할 수 없습니까? – Andriy

답변

1

LeoMaer,

당신은 당신이 그것을 추가 한도 전에 관찰자를 제거하려고 할 수 있습니다. 그래서 해결책은 관찰자를 제거하기 전에 그것을 추가했는지 확인하는 것입니다.

클래스의 init 또는 viewDidLoad에서 관찰자를 추가 한 다음 dealloc에서 제거하십시오.

반면에 특정 요구 사항이 있고 조건을 기반으로 추가해야하는 경우 충돌을 피하기 위해이를 사용하십시오.

이 문제를 해결하려면 추가 된 다른 예외가 사로 잡았 될 경우 관찰자를 제거하고 늘 충돌

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

카펫 아래의 문제를 숨기고 있습니까? – trojanfoe

+0

@trojanfoe : 정말로, 나는 그가 그를 제거하기 전에 관찰자를 추가했는지 확인하도록 권했다. 그러나 때로는 조건과 조건에 따라 관찰자를 추가 할 수 있음을 알기 때문에 언제나 사실이 아니기 때문에 관찰자를 추가하지 않고 iOS에서 불행하게도 끝날 수도있다. 관찰자가 추가되었는지 아닌지 확인하여 맹목적으로 원인을 제거하는 것이므로 추락을 일으키는 것이 더 낫다. :) 또한 관찰자를 확인하기위한 모든 답은 추가되거나 표시되지 않는다. 나는 개인적으로 좋아하지 않는다. 관찰자 및 알림 디자인 패턴을 사용하지만 누군가에게 도움이 될 수 있습니다. –

+0

@Sandeep Bhandari :이 방법이 효과가 있습니까? (NSString * keyPath in [self observableKeypaths]) { \t \t [self removeObserver : self forKeyPath : keyPath]; \t} – lme

1

것, 나는 해결책을 가지고있다.

는 @property NSMutableArray *observe_arr;을 가지고 excutive 경우 [self addObserver:self forKeyPath:@"observeName" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];observe_arrobserveName를 추가합니다. 의 dealloc에서

: 그런데

- (void)dealloc { 

    while (self.observe_arr.firstObject) { 

     [self removeObserver:self forKeyPath:self.observe_arr.firstObject]; 
    } 
} 

, 감사하기 Sandeep 반 다리의 많은 도움.

+0

소리가 들립니다 :) 다음 번에 시도해 보겠습니다. :) 따라서 투표 수 : :) 이 루프를 실행하면 해당 키에 대한 관찰자를 제거한 후 self.observe_arr에서 observeName을 제거해야합니다. 어쨌든 나는이 코드를 그대로 사용하는 것으로 믿는다. :) 누군가의 코드를 수정하기 전에 코드를 수정하십시오 :) –

관련 문제