Ich habe mich dazu entschieden, NSSecureCoding
über NSCoding
zu verwenden, aber ich habe Probleme damit, es zum Laufen zu bringen.
Ich würde erwarten, dass der folgende Code fehlschlägt, da ich ein NSString
codiere, aber versuche, ein NSNumber
zu dekodieren. Das Objekt wird jedoch initialisiert, ohne dass eine Ausnahme ausgelöst wird.
Hier ist der Code, den ich verwende, um das Snippet von oben zu testen:
%Vor%Fehle ich etwas völlig Offensichtliches oder warum wird beim Decodieren keine Ausnahme ausgelöst?
Wenn Sie sich die Definition von -[NSCoder decodeObjectOfClass:forKey:]
anschauen, sollte Ihr Code-Beispiel eine Ausnahme ausgelöst haben. Die Beschreibung der Methode sagt es:
Dekodiert ein Objekt für den Schlüssel, das auf die angegebene Klasse beschränkt ist.
Und die Diskussion sagt:
Wenn der Coder
YES
aufrequiresSecureCoding
antwortet, wird eine Exception ausgelöst, wenn die zu dekodierende Klasse nichtNSSecureCoding
implementiert oder nichtisKindOfClass:
von aClass.
Es gibt zwei Inkonsistenzen mit der Implementierung von NSKeyedUnarchiver
dieser Methode in Bezug auf Optimierungen. Die erste besteht darin, dass decodeObjectOfClass:forKey:
und decodeObjectForKey:
ein Objekt erst beim ersten Mal dekodieren.
Zum Beispiel wird das assert im folgenden Code übergeben, weil foo
und foo2
als dasselbe Objekt gestartet wurden und nur einmal dekodiert wurden, während foo3
als separates Objekt gestartet und als Ergebnis separat decodiert wurde.
Es scheint, dass Klassen nur überprüft werden, wenn das Objekt tatsächlich dekodiert wird. Die Liste der genehmigten Klassen wird mit der Klasse verglichen, die das Objekt anfordert. In meinem vorherigen Beispiel könnte ich also die Klasse für foo2
so ändern, wie ich möchte und der Code wird weiterhin ausgeführt und gibt NSSet
zurück:
Die zweite Inkonsistenz, die direkt mit Ihrem Beispiel zusammenhängt, ist, dass bestimmte Objekttypen niemals wirklich decodiert werden. NSKeyedArchiver
speichert alle seine Daten als eine Liste mit binären Eigenschaften, die nach Der Quelltext von Apple unterstützt native Zeichen-, Daten-, Zahlen-, Datums-, Wörterbuch- und Array-Typen. Wenn NSKeyedArchiver
auf ein NSString
, NSNumber
oder NSData
-Objekt (aber keine Unterklasse) trifft, speichert es den Wert nicht direkt in encodeWithObject:
und speichert Informationen über die Dekodierung der PList. Wenn Sie dann decodeObjectOfClass:withKey:
aufrufen, sieht es die bereits vorhandene Zeichenfolge und gibt sie ohne Dekodierung zurück. Keine Dekodierung bedeutet keine Klassenprüfung.
Ob dieses Verhalten gut oder schlecht ist, könnte diskutiert werden. Weniger Überprüfung bedeutet schneller Code, aber das Verhalten stimmt wirklich nicht mit der API-Dokumentation überein. Das heißt, Sie fragen sich vielleicht, welche sichere Codierung Sie bekommt, wenn es keine Rückgabetypen garantiert. Die sichere Kodierung mit NSKeyedUnarchiver
schützt Sie davor, dass ein in böser Absicht erstelltes Archiv Sie nicht dazu bringen kann, alloc / initWithCoder: in einer beliebigen Klasse aufzurufen. Wenn Sie mehr als das möchten, können Sie eine Unterklasse erstellen, die den Ausgabetyp aller decodeObjectOfClass:withKey:
und decodeObjectOfClasses:withKey:
call validiert.
Tags und Links objective-c ios cocoa nscoding nssecurecoding