Reputation: 499
I'm trying to fix up an old tutorial from RayWenderlich's site, no longer supported. The warning appears in three files, Chain.swift, Cookie.swift and Swap.swift from the "How to Make a Game Like Candy Crush with SpriteKit and Swift:" tutorial
I'm at a loss even after exploring the available replies that appear in many places. I'm struggling to understand just what this code is doing so that I can fix it. I know it's just a warning, and I can probably ignore it, but the game is also showing X where blank tiles should appear so I suspect that it may have something to do with this?
The warning is this:
'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'Chain' to 'Hashable' by implementing 'hash(into:)' instead
File example
class Chain: Hashable, CustomStringConvertible {
var cookies: [Cookie] = []
var score = 0
enum ChainType: CustomStringConvertible {
case horizontal
case vertical
var description: String {
switch self {
case .horizontal: return "Horizontal"
case .vertical: return "Vertical"
}
}
}
var chainType: ChainType
init(chainType: ChainType) {
self.chainType = chainType
}
func add(cookie: Cookie) {
cookies.append(cookie)
}
func firstCookie() -> Cookie {
return cookies[0]
}
func lastCookie() -> Cookie {
return cookies[cookies.count - 1]
}
var length: Int {
return cookies.count
}
var description: String {
return "type:\(chainType) cookies:\(cookies)"
}
var hashValue: Int {
return cookies.reduce (0) { $0.hashValue ^ $1.hashValue }
}
static func ==(lhs: Chain, rhs: Chain) -> Bool {
return lhs.cookies == rhs.cookies
}
}
Upvotes: 2
Views: 2656
Reputation: 539815
From the Hashable documentation:
Hashing a value means feeding its essential components into a hash function, represented by the Hasher type. Essential components are those that contribute to the type’s implementation of Equatable. Two instances that are equal must feed the same values to Hasher in hash(into:), in the same order.
And from the hash(into:)
documentation:
The components used for hashing must be the same as the components compared in your type’s == operator implementation. Call hasher.combine(_:) with each of these components.
The implementation of
static func ==(lhs: Chain, rhs: Chain) -> Bool {
return lhs.cookies == rhs.cookies
}
shows that cookies
is the “essential component” which determines equality of instances. Therefore
func hash(into hasher: inout Hasher) {
hasher.combine(cookies)
}
is a valid (and sensible) implementation of the Hashable
requirement.
Upvotes: 6