cast NSString! to String in swift
decodeObjectForKey
returns an optional AnyObject?
, so you have to guard your code against possible nil values. Using a cast to a forced unwrapped doesn't sound safe.
I am unable to reproduce the error (so the problem could be somewhere else in your code), but this is how I would approach when initializing the name
property:
var tempName = aDecoder.decodeObjectForKey("name") as? String
if let tempName = tempName {
self.name = tempName
} else {
self.name = "some initial value"
}
Note the usage of the optional downcasting as?
, which always produce a result (nil or a valid type value) as opposed to as NSString!
, which triggers an exception if the downcast is not possible (for instance if you are expecting a string, but it's an int instead).
That code would also allow you to better debugging - if tempName
is nil
, then either the key doesn't exist or the corresponding value is of a different type.
Arash
Updated on September 21, 2020Comments
-
Arash over 3 years
I have a instance variable name in String
var name: String
My class implements the NSCoding protocol. So for name I had
func encodeWithCoder(aCoder: NSCoder) { aCoder.encodeObject(self.name, forKey: kName) } required init(coder aDecoder: NSCoder) { self.name = aDecoder.decodeObjectForKey(kName) as String // CRASH HERE }
Result? I was getting a run time crash during initiation with decoder. I changed init to this:
var temp = aDecoder.decodeObjectForKey(kName) as NSString! self.name = aDecoder.decodeObjectForKey(kName) as String
and realised the value temp is holding the right NSString value. so I thought the line below is going to fix it but it issues a linker error:
self.name = aDecoder.decodeObjectForKey(kName) as NSString!
the questions is how to take the temp and put it into name?
-
jlehr over 9 yearsYou can replace your if/else logic with an expression using Swift's nil-coalescing operator as follows:
self.name = tempName ?? "some initial value"
-
Antonio over 9 yearsYeah good advice. I didn't use it just for clarity, but I didn't even mention :)
-
Arash over 9 yearsthanks for the answer. but the problem seem to be to cast from NSString! to String.
-
Arash over 9 yearsthanks for the answer. The problem is that the decodeObjectForKey seem to return an NSString that is never cartable to String. So the code you suggested never assigns a value to name property.
-
Antonio over 9 yearsNever heard of a
NSString
that cannot be cast toString
. Try saving whatdecodeObjectForKey
returns to aAnyObject?
variable, then assign totempName
via downcast, and use the debugger to step through the lines and see what's going on - hope that can help you figuring out -
HenryRootTwo over 9 yearsassert halts execution, last line will never be called, but what did you need it for?
-
Andy Dent almost 9 yearsassert only halts execution in debug builds - it's the same semantics as the C version. See the very cool blog post about how they built this developer.apple.com/swift/blog/?id=4