iOS 12のSDKからhashValue
の値が変わりました
Xcode 10で利用されるiOS 12のSDKでビルドしたアプリのhashValueの値が、Xcode 10より前にビルドした時の値と異なる値になっているようです。
iOS 12のSDKだと 1.hashValue の値が 1 じゃなくなってる
— Tatsuya Tanaka / たなたつ (@tanakasan2525) 2018年8月8日
Xcode 9.4.1で試すとIntのhashValueは自身の値と同じ
Xcode 9.4.1
Int
自身の値がhashValueの値。
例: 5.hashValue
なら 5
。
Bool
true
なら 1
、 false
なら 0
。
Enum
caseの順番がhashValueの値。
例
enum Foo {
case 🐶
case 🐱
case 🐭
}
print(Foo.🐱.hashValue) // 1
Xcode 10
Int
自身の値とは異なる値。
例: 5.hashValue
は、-1168890137408403414
など。 (実行のたびに変わるようです)
Bool
Intと同様。
Enum
Intと同様。
対応方法
本来の使い方で hashValue
を利用している場合は影響を受けないとは思いますが、誤った使用方法をしている場合は対応が必要です。
Int
.hashValue
を削除する。
例: 5.hashValue
なら 5
。
Bool
三項演算子で書き換える。
例
let flag = true
// Before
let value = flag.hashValue
// After
let value = flag ? 1 : 0
Enum
RawValue
にInt
を指定する。
例
// Before
enum Foo {
case 🐶
case 🐱
case 🐭
}
print(Foo.🐱.hashValue) // 1
// After
enum Foo: Int {
case 🐶
case 🐱
case 🐭
}
print(Foo.🐱.rawValue) // 1
既にRawValue
に別の型が使用されていたり、Associated Value
を利用している場合は、computed property
で Int
を返すプロパティを追加すると対応が簡単です。
例
enum Foo {
case 🐶(name: String)
case 🐱(name: String)
case 🐭(name: String)
var index: Int {
switch self {
case .🐶: return 0
case .🐱: return 1
case .🐭: return 2
}
}
まとめ
Xcode 10でアプリをビルドする際は一度、.hashValue
で検索をかけて、誤った使い方をしている部分がないかチェックをし、もしあった場合は上記のような対応をすると良いと思います。