I have the following test that succeeds in all Xcode versions released for last few years except for Xcode 12.5 beta 3:
var nilString: String? = nil
var dict: [String: Any] = ["hello": nilString as Any]
var element = dict["hello"] as Any
print(element)
print(type(of: element))
switch element {
case Optional<Any>.none:
print("element is nil")
default:
assertionFailure("element is not nil. wtf?")
}
In Xcode 12.4 I get this printed
Optional(nil)
Optional<Any>
element is nil
Wheras in Xcode 12.5 beta 3 I get this printed
Optional(nil)
Optional<Any>
Fatal error: element is not nil. wtf?
Can somebody shed some light on this issue? How can I check Any for nil now? Would it be fixed in release candidate?
UPDATED Want to be confused even more?
var nilString: String? = nil
var element: Any = nilString as Any
print(element)
print(type(of: element.self))
switch element {
case Optional<Any>.none:
print("element is nil")
default:
assertionFailure("element is not nil")
}
outputs:
nil
Optional<String>
element is nil
I suppose something wrong happens with my nilString when being put in dictionary.
Thanks to Jessy for pointing out on the idea that Optional<Any>
may actually have some
value inside and that could be nil
. I've come up with a function that checks Any for nil and it works in both old and newest Xcode (something has definitely been changed in 12.5 beta 3 that had broken the old test, i.e. putting nil casted to Any into a dictionary value leads the value to be wrapped into Optional<Any>.some
instead of treating it as Optional<Any>.none
):
func isOptional(_ instance: Any) -> Bool {
let mirror = Mirror(reflecting: instance)
let style = mirror.displayStyle
return style == .optional
}
func checkIfAnyIsNil(_ v: Any) -> Bool {
if (isOptional(v)) {
switch v {
case Optional<Any>.none:
return true
case Optional<Any>.some(let v):
return checkIfAnyIsNil(v)
default:
return false
}
} else {
return false
}
}
assertions:
var nilString: String? = nil
var dict: [String: Any] = ["nilString": nilString as Any]
assert(checkIfAnyIsNil(dict["nilString"] as Any))
assert(checkIfAnyIsNil(nilString as Any))
assert(checkIfAnyIsNil("some string" as Any) == false)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments