2

Consider the code:

struct S {
    var f : Int64 = 0
}

...

let coder : NSCoder = someCoder ...
let a : [Int] = []
coder.encodeObject(a)  // compiles
let b : [Int64] = []
coder.encodeObject(b)  // doesn't compile: not AnyObject
let s : [S] = []
coder.encodeObject(s)  // doesn't compile: not AnyObject

Note that Int is defined as a struct.

So [Int] is object, but [Int64] is not and neither is my array of simple structures.

What is special about Int?

rghome
  • 8,529
  • 8
  • 43
  • 62

3 Answers3

5

If you import Foundation (which you must be, because you reference NSCoder) then [Int] is implicitly bridged to NSArray because Int is implicitly bridged to NSNumber. Int64 and your non-objc structs are not implicitly bridged to ObjC types, so arrays of those are not bridged to NSArray.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Just for completeness, what other kinds of types, which when used in an array, are bridged to NSArray? – rghome Feb 15 '16 at 19:29
  • Anything that conforms to `_ObjectiveCBridgeable`. Command-click on `Foundation` to get to the `Foundation` interface, then search for `_ObjectiveCBridgeable`. – rob mayoff Feb 15 '16 at 19:30
  • See https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61 for the documentation. – Rob Napier Feb 15 '16 at 19:31
  • @rghome Related (w.r.t. rob mayoff:s comment): you can [extend e.g. `Int64` to conform to `_ObjectiveCBridgeable`](http://stackoverflow.com/questions/35893517/is-it-possible-to-replicate-swifts-automatic-numeric-value-bridging-to-foundatio) to allow the same implicit/automatic bridging as for `Int` in the example in your question; after which your `Int64` (elements) example will implicitly bridge to `NSNumber`, without need to explicitly perform this element-by-element `NSNumber` wrapping. – dfrib Mar 10 '16 at 07:01
  • 1
    @rghome Just take care to use the extension in practice, as `_ObjectiveCBridgeable` is a Swift internal/non-public protocol that might—for any Swift update—introduce, without notice, breaking changes to any custom code of ours making direct use of (conformance to) it. – dfrib Mar 10 '16 at 08:39
3

Int is bridged (as are UInt and Float and Double, as well as Bool). This means that they are wrapped up in an NSNumber for you, automatically, when you cast to AnyObject, and vice versa.

Other numeric types, alas, are not.

In turn, you also get to take advantage of array-casting syntactic sugar. An NSArray must consist of Objective-C objects, such as NSNumber. When you start with a Swift array, instead of having to wrap the elements up in an NSNumber yourself, as you do with an array of Int64, they are wrapped for you when you cast/bridge a Swift array to an NSArray.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • For more details on what types are bridged, see the appendix to my book: http://www.apeth.com/swiftBook/apa.html#_objective_c_objects_and_swift_objects – matt Feb 15 '16 at 19:28
  • OK - thanks. You answered the comment to the other question. – rghome Feb 15 '16 at 19:30
1

If Foundation framework is imported, Int (unlike Int64) is implicitly bridged to NSNumber which conforms to AnyObject

vadian
  • 274,689
  • 30
  • 353
  • 361