5

The following code crashes on Swift 3, can anyone please explain why?

struct S {
    let a:Int
}

let t = [S(a: 8)]
let u:AnyObject = t as NSObject
let v:[S] = u as! [S]

Is that because in Swift 3 array of structs is NSObject (it's not in Swift 2) and it somehow can't be converted to NSArray well? And why is it NSObject?..

JAL
  • 41,701
  • 23
  • 172
  • 300
silyevsk
  • 4,021
  • 3
  • 31
  • 30
  • Does `let u:AnyObject = t as NSObject` even compile for you...? Arrays in swift are value types and does naturally not derive from the concrete class type `NSObject`. In Swift 2 implicit bridging between Swift native types and Obj-C types could allow for slightly confusing conversions, but implicit bridging facilities has been removed in Swift 3. – dfrib Oct 19 '16 at 14:50
  • This is weird, since `let v = u as? [S]` works. – JAL Oct 19 '16 at 15:03
  • @dfri - yes, it compiles, may be it's a bug in Swift 3.. – silyevsk Oct 19 '16 at 15:22
  • @silyevsk Ok, I've only tested for Swift 3 at the IBM sandbox (where it does not work). – dfrib Oct 19 '16 at 15:24
  • 1
    @JAL - indeed, and then the optional can be unwrapped, so you solved the issue for me :) – silyevsk Oct 19 '16 at 15:30
  • Added an answer to help future visitors. – JAL Oct 19 '16 at 15:33

1 Answers1

3

A possible solution would be to use a conditional binding with an optional downcast:

if let v = u as? [S] { /* */ }

Not sure why forced downcast wouldn't work though. Might be something funky going on with NSObject.

JAL
  • 41,701
  • 23
  • 172
  • 300