2015-05-11 3 views
18

Ich habe einige Probleme mit den folgenden Crash-Logs aus dem Abschnitt "Abstürze" in Xcode. Nur wenige Geräte sind von diesem Absturzbericht betroffen.Absturz mit removeObserver: forKeyPath: in Foundation

Ich habe das Problem analysiert, aber ich denke, es ist ein Fehler auf Apple-Framework. Aber ich kann keinen Weg finden, es zu replizieren.

Hier eine ähnliche Diskussion: Help with crash in removeObserver:forKeyPath:.

Irgendwelche Hinweise?

Themen 0 Name: Thread 0 Abgestürzt:

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

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

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

3 Foundation
0x235069a7 - [NSObject (NSKeyValueObserverRegistration) removeObserver: forKeyPath: Kontext:] + 219 (NSKeyValueObserving.m: 1663)

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

wo removeObjectObserver:forKeyPath: ist

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

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

    } @catch (NSException *exception) { } 
} 

Antwort

6

Observers in Objective-C müssen mit extra Aufmerksamkeit verwendet werden: nicht den gleichen Beobachter Multiples Zeit auf das gleiche Objekt der Eigenschaft hinzufügen, und wickeln Sie die Entfernung, wenn es eine gibt:

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

Sie stürzen ab, weil Sie versuchen, den Beobachter zweimal zu entfernen, oder Sie entfernen einen nicht existenten Beobachter.

Sie sollen observers auf diese Weise hinzufügen:

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

EDIT: Sie können einen Beobachter an einem bereits ausplanen Objekt entfernen, in diesem Absturz führen.

+0

[self observationInfo] diese codition nicht befriedigend ist! sollte ich [yourObject Beobachtungsinfo] überprüfen? –

3

Normalerweise haben Sie einen ivar, um zu wissen, ob der Schlüsselpfad Ihres Objekts im Moment beobachtet wird oder nicht. Wie @property (...) BOOL textFieldTextObserving; Und Ihre Add/Remove-Observing-Methoden sollten diese Eigenschaft vor dem Hinzufügen/Entfernen überprüfen, um das Hinzufügen/Entfernen von Beobachter zweimal zu vermeiden. Sie können NSDictionary auch verwenden, wenn es viele beobachtende Objekte und Schlüsselpfade gibt (um @ (BOOL) als Objekte und -Identifikationen als Schlüssel zu behalten).

Wie auch immer, Dinge mit @ try-exception zu tun ist keine empfohlene Objective-C-Methode. Apple-docs sagt:

"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