I'm trying to get an unwrapped type from an optional type in runtime.
The following code would print the type of a as Optional<String>
.
class MySubClass: MyClass {
var a: String? = nil
}
var a = MySubClass()
let mirror = Mirror(reflecting: a)
for child in mirror.children {
print(child.value.dynamicType)
}
Now I want to unwrap the type and get String
, what should I do to make this happen in runtime?
If you know that an optional definitely has a value, you can force unwrap it by placing this exclamation mark after it. If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. Putting an exclamation mark at the end of the variable. var mycodetipsString:String? mycodetipsString = "Hello, Swift !"
However there is another data type in Swift called Optional, whose default value is a null value (nil). You can use optional when you want a variable or constant contain no value in it. An optional type may contain a value or absent a value (a null value). Non technically, you can think optional as a shoe box.
In Objective-C, C-based variables (primitives) always had to have a value, but object types could either be a valid object, or a pointer to nil. Swift optionals allow you to make any type in Swift into a nil-able type (though this nil is not exactly the same as an Objective-C nil).
One way to use Swift Optionals in places that don’t take them, is to forcefully change them back into normal variables. Apparently you question a variable to make it into an optional, and you yell at at it to forcefully unwrap it: Yep, that exclamation point forcefully unwraps it. There is a problem though.
Assuming you have an optional
let someVar: String?
then print(type(of: someVar))
will print
Optional<String>
but if you add the following extension to Optional
protocol OptionalProtocol {
func wrappedType() -> Any.Type
}
extension Optional: OptionalProtocol {
func wrappedType() -> Any.Type {
return Wrapped.self
}
}
then print(someVar.wrappedType())
will print
String
No reflection whatsoever
Summary
As long as the optional is not referenced by Any
or AnyObject
the code will work fine.
For Any
you will have to cast it to OptionalProtocol
first. Running
let someVar: String?
let anyVar = someVar as Any
if let op = anyVar as? OptionalProtocol {
print(op.wrappedType())
}
will print
String
As for AnyObject
, strangely enough (at least for me), it doesn't cast to OptionalProtocol
.
The original StackOverflow answer can be found here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With