What are the properties of Foundations AnyObject.hash

Using XCode I discovered that importing Foundation adds a property hash: Int? to AnyObject:

import Foundation

let str = "Hello, playground"
let int = 12
let double = 1.0
let bool = false

class A: Hashable {
    var i = 2
    
    static func == (lhs: A, rhs: A) -> Bool {
        return lhs.i == rhs.i
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(i)
    }
}

class B {
    var b = false
}

class C {
    var b: B? = nil
}

let a = A()
let b = B()
let c = C()

(str as AnyObject).hash // some number
(int as AnyObject).hash // some number
(double as AnyObject).hash // some number
(bool as AnyObject).hash // 0
(a as AnyObject).hash // some number
(b as AnyObject).hash // some number
(c as AnyObject).hash // some number

(c as AnyObject).hash == (c as AnyObject).hash // true

let a2 = A()
(a as AnyObject).hash == (a2 as AnyObject).hash // false

However, I googled till my fingers bleeded, but I could not find any documentation about this except the sentence XCode displays: "Returns an Integer that can be used as a table address in a hash table structure". Also the Jump to Definition results arent very helpfull: Bildschirmfoto 2020-04-26 um 17.42.10

Many things remain unclear to me: Why is it optional? When will it return nil? Is it identity based, as appears to be on first sight... Is it safe to use it, if I want to create a Dictionary of AnyObjects => Why is AnyObject not Hashable then?

Pointers to the corresponding documentation or any answers to the questions above would be very much apprechiated :slight_smile:

1 Like

Compare https://developer.apple.com/documentation/swift/anyobject:

When you use AnyObject as a concrete type, you have at your disposal every @objc method and property—that is, methods and properties imported from Objective-C or marked with the @objc attribute. Because Swift can’t guarantee at compile time that these methods and properties are actually available on an AnyObject instance’s underlying type, these @objc symbols are available as implicitly unwrapped optional methods and properties, respectively.

So

let int = 12
let h = (int as AnyObject).hash

returns the hash property of NSObject (in this case: NSNumber) as an optional. Another example:

print(("abc" as AnyObject).capitalized) // Optional("Abc")
print((123 as AnyObject).capitalized) // nil

capitalized is a property of NSString (to which "abc" is bridged), but not of NSNumber (to which 123 is bridged).

1 Like

Thank you for pointing this out! Now I know where to look :slight_smile: