2015-10-05 23 views
6

Mam klasy, która serializuje i deserializacji z NSCoder/NSKeyedArchiver i NSKeyedUnarchiver. Mam testy jednostkowe, które zostały zaprojektowane w celu sprawdzenia mojego postępowania z różnymi błędami w moim formacie serializacji (który nie jest zwykłym archiwum, ale zawiera archiwa).NSKeyedUnarchiver unarchiveObjectWithData return nil

Jednak od czasu przejścia na wersję Swift 2/iOS 9 testy wykazują nietypowe zachowanie. Wcześniej test niepoprawnych archiwów nie powiódł się, ponieważ w wyniku deserializacji nieprawidłowe archiwum rzuciło wyjątek Objective-C, jak stwierdza dokument, który spowodował awarię programu, ponieważ Swift nie mógł ich złapać. To jest w porządku, zamierzałem naprawić test w pewnym momencie w przyszłości.

Teraz test przechodzi. Kiedy karmię moje losowe lub deterministyczne śmieci, zamiast odbierać nil z powrotem zamiast unarchiveObjectWithData zamiast wyjątku. Sprawdziłem dokumenty dla tej metody i nie wymieniono żadnej zmiany zachowania.

Szczerze mówiąc, uważam, że to zachowanie jest niezwykle podejrzane, ponieważ nigdzie nie ma wzmianki o tym, jak i dlaczego ta zmiana wystąpiła. Moje wcześniej nieudane testy jednostkowe właśnie przechodzą bez wyraźnego powodu.

Czy to nowe oczekiwane zachowanie (które zwraca nil)? Jeśli nie, jak uzyskać rzeczywiste oczekiwane zachowanie (wyjątek Obj-C) zamiast nil dla niepoprawnego archiwum?

Odpowiedz

3

Swift2/iOS9 wprowadza nieudokumentowanethrows klasy metody w NSKeyedUnarchiver:

extension NSKeyedUnarchiver { 
    @warn_unused_result 
    public class func unarchiveTopLevelObjectWithData(data: NSData) throws -> AnyObject? 
} 

Ale to nie wydaje się działać, jeśli dane są całkowicie błędne format: Zwraca nil bez błędu.

let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)! 
try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(dat) // -> `nil` 

Błędy są zgłaszane tylko wtedy, gdy unarchiver wykrył pewne nieprawidłowe elementy (np. Nieznaną nazwę klasy) podczas dekodowania. Myślę, że to rodzaj błędu lub jest przypadkowo wydany z niepełnymi implementacjami.

W każdym razie, jeśli chcesz, Objective-C wyjątek, można po prostu skonstruować NSKeyedUnarchiver:

let dat = "test".dataUsingEncoding(NSUTF8StringEncoding)! 
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat) // -> throws Objective-C exception 

Ale nie ma throws inicjator ... jeszcze?

+0

Dzięki za to. Myślę, że skonstruuję NSKeyedArchiver i ręcznie obsłużyłem ten wyjątek ObjC na teraz, więc nie jestem w tym dziwnym, nieudokumentowanym, w połowie wdrożonym kroku. – Puppy

Powiązane problemy