Skip to content

Commit 0a8d729

Browse files
committed
Foundation: more idiomatic swift in NSKeyedArchiver
Eliminate some force-unwrap/force-casts in NSKeyedArchiver and NSKeyedUnarchiver. Some notes about whether unarchiver delegate is called when decoding nil objects.
1 parent a028e06 commit 0a8d729

File tree

2 files changed

+36
-37
lines changed

2 files changed

+36
-37
lines changed

Sources/Foundation/NSKeyedArchiver.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,11 +405,12 @@ open class NSKeyedArchiver : NSCoder {
405405
Returns true if the object has already been encoded.
406406
*/
407407
private func _haveVisited(_ objv: Any?) -> Bool {
408-
if objv == nil {
409-
return true // always have a null reference
410-
} else {
411-
return self._objRefMap[__SwiftValue.store(objv!)] != nil
408+
guard let objv = objv else {
409+
// always have a null reference
410+
return true
412411
}
412+
413+
return self._objRefMap[__SwiftValue.store(objv)] != nil
413414
}
414415

415416
/**

Sources/Foundation/NSKeyedUnarchiver.swift

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ open class NSKeyedUnarchiver : NSCoder {
201201
}
202202

203203
private func _objectInCurrentDecodingContext<T>(forKey key: String?) -> T? {
204-
var unwrappedKey = key
204+
let unwrappedKey: String
205205

206-
if key != nil {
207-
unwrappedKey = escapeArchiverKey(key!)
206+
if let key = key {
207+
unwrappedKey = escapeArchiverKey(key)
208208
} else {
209209
unwrappedKey = _nextGenericKey()
210210
}
211211

212-
if let v = _currentDecodingContext.dict[unwrappedKey!] {
212+
if let v = _currentDecodingContext.dict[unwrappedKey] {
213213
return v as? T
214214
}
215215
return nil
@@ -272,18 +272,18 @@ open class NSKeyedUnarchiver : NSCoder {
272272
}
273273

274274
private func _isClassAllowed(_ assertedClass: AnyClass?, allowedClasses: [AnyClass]?) -> Bool {
275-
if assertedClass == nil {
275+
guard let assertedClass = assertedClass else {
276276
return false
277277
}
278278

279279
if _flags.contains(.requiresSecureCoding) {
280280
if let unwrappedAllowedClasses = allowedClasses {
281-
if unwrappedAllowedClasses.contains(where: {NSKeyedUnarchiver._classIsKindOfClass(assertedClass!, $0)}) {
281+
if unwrappedAllowedClasses.contains(where: {NSKeyedUnarchiver._classIsKindOfClass(assertedClass, $0)}) {
282282
return true
283283
}
284284
}
285285

286-
fatalError("Value was of unexpected class \(assertedClass!)")
286+
fatalError("Value was of unexpected class \(assertedClass)")
287287
} else {
288288
return true
289289
}
@@ -320,16 +320,16 @@ open class NSKeyedUnarchiver : NSCoder {
320320
let assertedClassHints = unwrappedClassDict["$classhints"] as? [String]
321321
let assertedClasses = unwrappedClassDict["$classes"] as? [String]
322322

323-
if assertedClassName != nil {
324-
let assertedClass : AnyClass? = _classForClassName(assertedClassName!)
323+
if let assertedClassName = assertedClassName {
324+
let assertedClass : AnyClass? = _classForClassName(assertedClassName)
325325
if _isClassAllowed(assertedClass, allowedClasses: allowedClasses) {
326326
classToConstruct = assertedClass
327327
return true
328328
}
329329
}
330330

331-
if assertedClassHints != nil {
332-
for assertedClassHint in assertedClassHints! {
331+
if let assertedClassHints = assertedClassHints {
332+
for assertedClassHint in assertedClassHints {
333333
// FIXME check whether class hints should be subject to mapping or not
334334
let assertedClass : AnyClass? = NSClassFromString(assertedClassHint)
335335
if _isClassAllowed(assertedClass, allowedClasses: allowedClasses) {
@@ -339,11 +339,11 @@ open class NSKeyedUnarchiver : NSCoder {
339339
}
340340
}
341341

342-
if assertedClassName != nil {
342+
if let assertedClassName = assertedClassName {
343343
if let unwrappedDelegate = self.delegate {
344344
classToConstruct = unwrappedDelegate.unarchiver(self,
345-
cannotDecodeObjectOfClassName: assertedClassName!,
346-
originalClasses: assertedClasses != nil ? assertedClasses! : [])
345+
cannotDecodeObjectOfClassName: assertedClassName,
346+
originalClasses: assertedClasses ?? [])
347347
if classToConstruct != nil {
348348
return true
349349
}
@@ -417,28 +417,26 @@ open class NSKeyedUnarchiver : NSCoder {
417417
}
418418

419419
private func _replacementObject(_ decodedObject: Any?) -> Any? {
420-
var object : Any? = nil // object to encode after substitution
421-
422-
// nil cannot be mapped
423-
if decodedObject == nil {
420+
// nil cannot be mapped (this appears to differ from Darwin?)
421+
guard let decodedObject = decodedObject else {
424422
return nil
425423
}
426424

427425
// check replacement cache
428-
object = self._replacementMap[__SwiftValue.store(decodedObject!)]
429-
if object != nil {
426+
if let object = self._replacementMap[__SwiftValue.store(decodedObject)] {
430427
return object
431428
}
432-
433-
// object replaced by delegate. If the delegate returns nil, nil is encoded
429+
430+
// object replaced by delegate. If using ARC, the delegate should only return
431+
// nil if the object itself is nil.
434432
if let unwrappedDelegate = self.delegate {
435-
object = unwrappedDelegate.unarchiver(self, didDecode: decodedObject!)
436-
if object != nil {
437-
replaceObject(decodedObject!, withObject: object!)
438-
return object
439-
}
433+
let object = unwrappedDelegate.unarchiver(self, didDecode: decodedObject)
434+
if object != nil {
435+
replaceObject(decodedObject, withObject: object!)
436+
return object
437+
}
440438
}
441-
439+
442440
return decodedObject
443441
}
444442

@@ -470,12 +468,12 @@ open class NSKeyedUnarchiver : NSCoder {
470468
throw InternalError.decodingHasAlreadyFailed
471469
}
472470

473-
if !(objectRef is _NSKeyedArchiverUID) {
471+
guard let objectRef = objectRef as? _NSKeyedArchiverUID else {
474472
throw _decodingError(.coderReadCorrupt,
475473
withDescription: "Object \(objectRef) is not a reference. The data may be corrupt.")
476474
}
477-
478-
guard let dereferencedObject = _dereferenceObjectReference(objectRef as! _NSKeyedArchiverUID) else {
475+
476+
guard let dereferencedObject = _dereferenceObjectReference(objectRef) else {
479477
throw _decodingError(.coderReadCorrupt,
480478
withDescription: "Invalid object reference \(objectRef). The data may be corrupt.")
481479
}
@@ -486,7 +484,7 @@ open class NSKeyedUnarchiver : NSCoder {
486484

487485
if _isContainer(dereferencedObject) {
488486
// check cached of decoded objects
489-
object = _cachedObjectForReference(objectRef as! _NSKeyedArchiverUID)
487+
object = _cachedObjectForReference(objectRef)
490488
if object == nil {
491489
guard let dict = dereferencedObject as? Dictionary<String, Any> else {
492490
throw _decodingError(.coderReadCorrupt,
@@ -523,7 +521,7 @@ open class NSKeyedUnarchiver : NSCoder {
523521
withDescription: "Class \(classToConstruct!) failed to decode. The data may be corrupt.")
524522
}
525523

526-
_cacheObject(object!, forReference: objectRef as! _NSKeyedArchiverUID)
524+
_cacheObject(object!, forReference: objectRef)
527525
}
528526
} else {
529527
object = __SwiftValue.store(dereferencedObject)

0 commit comments

Comments
 (0)