2015-05-11 16 views
18

Mam problemy z następującymi logami awarii pobranymi z sekcji "Crashes" w Xcode. Ten raport awarii dotyczy tylko kilku urządzeń.Awaria przy użyciu removeObserver: forKeyPath: in Foundation

Przeanalizowałem problem, ale myślę, że to błąd w środowisku Apple. Ale nie mogę znaleźć sposobu, aby to powtórzyć.

Tutaj podobna dyskusja: Help with crash in removeObserver:forKeyPath:.

Jakieś wskazówki?

wątek 0 Nazwa: wątek 0 Uszkodzony:

0 fundamentowych
0x23507591 _NSKeyValueReplaceObservationInfoForObject + 69 (NSKeyValueObserving.m: 1166)

1 Foundation
0x23506fe7 - [NSObject (NSKeyValueObserverRegistration) _removeObserver: forProperty:] + 327 (NSKeyValueObserving.m: 1552)

2 Podstawą
0x23506b03 - [NSObject (NSKeyValueObserverRegistration) removeObserver: forKeyPath:] + 163 (NSKeyValueObserving.m: 1696)

3 podstawą
0x235069a7 - [NSObject (NSKeyValueObserverRegistration) removeObserver: forKeyPath: kontekst:] + 219 (NSKeyValueObserving.m: 1663)

4 NazwaAplikacji 0x0002e233 - [Promotor removeObjectObserver: forKeyPath:] + 115 (Supervisor.m: 344)

gdzie removeObjectObserver:forKeyPath: jest

- (void) removeObjectObserver:(id)object forKeyPath:(NSString *)keyPath { 

    @try {   
     [object removeObserver:self forKeyPath:keyPath context:PrivateKVOContext]; 

    } @catch (NSException *exception) { } 
} 

Odpowiedz

6

Observers w Objective-C musi być używany z dodatkowej uwagi: nie dodawać w tym samym czasie wielokrotności obserwator własności tego samego obiektu, a owinąć usunięcie jeśli jest jedna:

if ([self observationInfo]) { 
     @try { 
      [self removeObserver:self forKeyPath:keyPath]; 
     } 
     @catch (NSException *exception) {} 
    } 

Występują awarie, ponieważ próbujesz usunąć dwa razy obserwatora lub usuwasz nieistniejącego obserwatora.

Należy dodać observers ten sposób:

[yourObject addObserver:self forKeyPath:keypath options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial context:nil/yourContext]; 

EDIT: Możesz usunąć obserwatora na już zwalnianie obiektu, w wyniku tej katastrofy.

+0

[self observationInfo] ten codition nie jest zadowalająca! czy powinienem sprawdzić [yourObject observationInfo]? –

3

Zazwyczaj masz ivar, aby wiedzieć, czy w danej chwili obserwujesz obiekt, czy nie. Podobnie jak @property (...) BOOL textFieldTextObserving; Twoje metody dodawania i usuwania powinny sprawdzić tę właściwość przed dodaniem/usunięciem, aby uniknąć dwukrotnego dodawania/usuwania obserwatora. Możesz także użyć NSDictionary, jeśli istnieje wiele obiektów obserwujących i keypathów (aby zachować @ (BOOL) jako obiekty i -identyfikatory jako klucze).

W każdym razie, robienie rzeczy przy użyciu @ try-wyjątku nie jest zalecanym sposobem na Cel-C. Jabłko docs mówi:

"You should not use a try-catch block in place of standard programming checks for Objective-C methods. In the case of an NSArray, for example, you should always check the array’s count to determine the number of items before trying to access an object at a given index. The objectAtIndex: method throws an exception if you make an out-of-bounds request so that you can find the bug in your code early in the development cycle—you should avoid throwing exceptions in an app that you ship to users." https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html