6

How can we check if a parameter passed in a function is a value or a reference type? For example

func isReferenceType(toTest: Any) {
    return true // or false
}

As we see here, we are not able to do this leveraging generics.

Community
  • 1
  • 1
Michael Dorner
  • 17,587
  • 13
  • 87
  • 117

2 Answers2

7

AnyObject is a protocol that any class type automatically conforms to, so you can write:

func isReferenceType(toTest: Any) -> Bool {
    return toTest.dynamicType is AnyObject
}

class Foo { }
struct Bar { }

isReferenceType(Foo())    // true
isReferenceType(Bar())    // false
isReferenceType("foo")    // false
isReferenceType(123)      // false
isReferenceType([1,2,3])  // false
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
  • 2
    Yes, but `isReferenceType("foo")` or `isReferenceType(123)` or `isReferenceType([1, 2, 3])` will also return `true` (if Foundation is imported). – Martin R Jan 11 '16 at 15:49
  • 1
    Ah, the old silent cast. Checking the dynamic type instead of the value itself seems to resolve that... – Nate Cook Jan 11 '16 at 15:52
  • 1
    Or alternatively: `func isReferenceType(toTest: T) -> Bool { return !(T.self is AnyObject) }` – Michael Dorner Jan 11 '16 at 16:10
5

Swift 5

func isReferenceType(_ toTest: Any) -> Bool {
    return type(of: toTest) is AnyClass
}
iUrii
  • 11,742
  • 1
  • 33
  • 48