In meinen Komponententests verwende ich die Methode -[XCTestCase keyValueObservingExpectationForObject:keyPath:handler:]
, um sicherzustellen, dass meine NSOperation beendet ist, hier ist der Code aus meinem XCDYouTubeKit-Projekt :
Dieser Test wird immer ausgeführt, wenn ich ihn lokal auf meinem Mac ausführe, aber manchmal funktioniert auf Travis nicht mit diesem Fehler:
failed: hat "NSRangeException" abgefangen, "kann einen Beobachter & lt; _XCKVOExpectation 0x1001846c0 & gt; für den Schlüsselpfad" isFinished "von & lt; XCDYouTubeVideoOperation 0x1001b9510 & gt; nicht entfernen, da er nicht als Beobachter registriert ist."
Mache ich etwas falsch?
Ihr Code ist korrekt, Sie haben einen Fehler im XCTest-Framework gefunden. Hier ist eine ausführliche Erklärung, Sie können zum Ende dieser Antwort springen, wenn Sie nur nach einem Workaround suchen.
Wenn Sie keyValueObservingExpectationForObject:keyPath:handler:
aufrufen, wird ein _XCKVOExpectation
-Objekt unter der Haube erstellt. Es ist dafür verantwortlich, das von Ihnen übergebene Objekt / keyPath zu beobachten. Sobald die KVO-Benachrichtigung ausgelöst wurde, wird die Methode _safelyUnregister
aufgerufen. Hier wird der Beobachter entfernt. Hier ist die (reverse engineered) Implementierung der Methode _safelyUnregister
.
Diese Methode wird am Ende von waitForExpectationsWithTimeout:handler:
erneut aufgerufen und wenn das Objekt _XCKVOExpectation
freigegeben wird. Beachten Sie, dass die Operation in einem Hintergrundthread endet, der Test jedoch im Hauptthread ausgeführt wird. Sie haben also eine Racebedingung: Wenn _safelyUnregister
für den Hauptthread aufgerufen wird, bevor die hasUnregistered
-Eigenschaft im Hintergrundthread auf YES
gesetzt ist, wird der Beobachter zweimal entfernt, wodurch Einen Beobachter nicht entfernen
Um dieses Problem zu umgehen, müssen Sie die Methode _safelyUnregister
mit einer Sperre schützen. Hier ist ein Code-Snippet, das Sie in Ihr Testziel kompilieren können, das sich um die Behebung dieses Fehlers kümmert.
BEARBEITEN
Dieser Fehler wurde in Xcode 7 beta 4 behoben .
Tags und Links ios macos key-value-observing xctest