Skip to content

Commit b50294a

Browse files
authored
Merge pull request #18257 from lorentey/NSObject-hashing2
[ObjectiveC] NSObject: Clarify hashing implementation
2 parents 175db41 + d03786e commit b50294a

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

stdlib/public/SDK/ObjectiveC/ObjectiveC.swift

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,25 +195,56 @@ public var NO: ObjCBool {
195195
//===----------------------------------------------------------------------===//
196196

197197
// NSObject implements Equatable's == as -[NSObject isEqual:]
198-
// NSObject implements Hashable's hashValue() as -[NSObject hash]
198+
// NSObject implements Hashable's hashValue as -[NSObject hash]
199199
// FIXME: what about NSObjectProtocol?
200200

201201
extension NSObject : Equatable, Hashable {
202+
/// Returns a Boolean value indicating whether two values are
203+
/// equal. `NSObject` implements this by calling `lhs.isEqual(rhs)`.
204+
///
205+
/// Subclasses of `NSObject` can customize Equatable conformance by overriding
206+
/// `isEqual(_:)`. If two objects are equal, they must have the same hash
207+
/// value, so if you override `isEqual(_:)`, make sure you also override the
208+
/// `hash` property.
209+
///
210+
/// - Parameters:
211+
/// - lhs: A value to compare.
212+
/// - rhs: Another value to compare.
202213
public static func == (lhs: NSObject, rhs: NSObject) -> Bool {
203214
return lhs.isEqual(rhs)
204215
}
205216

206217
/// The hash value.
207218
///
219+
/// `NSObject` implements this by returning `self.hash`. Subclasses can
220+
/// customize hashing by overriding the `hash` property.
221+
///
208222
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
209223
///
210224
/// - Note: the hash value is not guaranteed to be stable across
211225
/// different invocations of the same program. Do not persist the
212226
/// hash value across program runs.
213-
@objc
214-
open var hashValue: Int {
227+
@objc open // FIXME: Should be @nonobjc public. rdar://problem/42623458
228+
var hashValue: Int {
215229
return hash
216230
}
231+
232+
/// Hashes the essential components of this value by feeding them into the
233+
/// given hasher.
234+
///
235+
/// NSObject implements this by feeding `self.hash` to the hasher. Subclasses
236+
/// can customize hashing by overriding the `hash` property.
237+
public func hash(into hasher: inout Hasher) {
238+
// FIXME: We should combine self.hash here, but hashValue is currently
239+
// overridable.
240+
hasher.combine(hashValue)
241+
}
242+
243+
public func _rawHashValue(seed: (UInt64, UInt64)) -> Int {
244+
// FIXME: We should use self.hash here, but hashValue is currently
245+
// overridable.
246+
return self.hashValue._rawHashValue(seed: seed)
247+
}
217248
}
218249

219250
extension NSObject : CVarArg {

0 commit comments

Comments
 (0)