Swift hashValue崩溃了应用程序

kdg*_*ill 12 string swift

出于某种原因,在实现对象hashValue以便在其他结构中使用时,程序崩溃了.当我尝试获取任何字符串对象的hashCode时,它似乎崩溃了.它正在扩展一个结构,但是随着时间的推移,使用了hashValue,已经定义了被访问的字段.我通过测试诸如"TEST"之类的字符串来扩展它,它仍然崩溃.整数hashValues如id字段都可以.任何援助将不胜感激.

Swift 1.2 Xcode 6.4

extension SwiftObject:Hashable{//Hashable inherits Equatable and used for sets
    var hashValue: Int {
        let prime:Int = 31;
        var result:Int = 17;
        result = prime * result + id.hashValue
        result = prime * result + name.hashValue
        var locationString:String = "\(location.latitude.hashValue), \(location.longitude.hashValue)"
        result = prime * result + locationString.hashValue
        return result
    }
}

func == (lhs: Object, rhs: Object) -> Bool {
    let primaryBool:Bool = lhs.id == rhs.id
    let secondaryBool:Bool = lhs.name == rhs.name
    let thirdBool:Bool = lhs.location.distance(rhs.location) == 0
    return primaryBool || (secondaryBool && thirdBool)
}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

* thread #1: tid = 0x6c2b4, 0x000000010f021af3 IphoneApplication`IphoneApplication.AppStruct.hashValue.getter : Swift.Int(self=IphoneApplication.AppStruct at 0x00007fff50befde8) + 2771 at IphoneApplication.swift:96, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x000000010f021af3 IphoneApplication`IphoneApplication.AppStruct.hashValue.getter : Swift.Int(self=IphoneApplication.AppStruct at 0x00007fff50befde8) + 2771 at IphoneApplication.swift:96
    frame #1: 0x000000010f02302b IphoneApplication`protocol witness for Swift.Hashable.hashValue.getter : Swift.Int in conformance IphoneApplication.AppStruct : Swift.Hashable in IphoneApplication + 651 at IphoneApplication.swift:88
    frame #2: 0x0000000111fc1aad libswiftCore.dylib`Swift._NativeSetStorage._bucket <A : Swift.Hashable>(Swift._NativeSetStorage<A>)(A) -> Swift.Int + 29
    frame #3: 0x0000000111fd071e libswiftCore.dylib`Swift._VariantSetStorage.nativeUpdateValue <A : Swift.Hashable>(inout Swift._VariantSetStorage<A>)(A, forKey : A) -> Swift.Optional<A> + 334
    frame #4: 0x0000000111fbb344 libswiftCore.dylib`Swift._VariantSetStorage.updateValue <A : Swift.Hashable>(inout Swift._VariantSetStorage<A>)(A, forKey : A) -> Swift.Optional<A> + 52
    frame #5: 0x0000000111fbb2c0 libswiftCore.dylib`Swift.Set.insert <A : Swift.Hashable>(inout Swift.Set<A>)(A) -> () + 144
    frame #6: 0x000000010f032592 IphoneApplication`IphoneApplication.FoursquarePlacesService.(result=0x00007fcfc87700d0, self=0x00007fcfca825c90) -> (IphoneApplication.WOMapUI, searchTerm : Swift.String) -> Swift.Set<IphoneApplication.AppStruct>).(closure #1) + 8162 at FoursquarePlacesService.swift:102
    frame #7: 0x000000010f032917 IphoneApplication`reabstraction thunk helper from @callee_owned (@owned QuadratTouch.Result) -> (@unowned ()) to @callee_owned (@in (result : QuadratTouch.Result)) -> (@out ()) + 23 at FoursquarePlacesService.swift:0
    frame #8: 0x000000010f02d171 IphoneApplication`partial apply forwarder for reabstraction thunk helper from @callee_owned (@owned QuadratTouch.Result) -> (@unowned ()) to @callee_owned (@in (result : QuadratTouch.Result)) -> (@out ()) + 81 at FoursquarePlacesService.swift:0
    frame #9: 0x0000000111e19150 QuadratTouch`reabstraction thunk helper from @callee_owned (@in (result : QuadratTouch.Result)) -> (@out ()) to @callee_owned (@owned QuadratTouch.Result) -> (@unowned ()) + 32 at Task.swift:0
    frame #10: 0x0000000111e190f8 QuadratTouch`QuadratTouch.DataTask.(self=0x00007fcfcd004100, result=0x00007fcfc87700d0) -> () -> ()).(closure #1).(closure #1) + 232 at Task.swift:71
    frame #11: 0x0000000111e19187 QuadratTouch`reabstraction thunk helper from @callee_owned () -> (@unowned ()) to @callee_unowned @objc_block () -> (@unowned ()) + 39 at Task.swift:0
    frame #12: 0x00000001100a757f Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
    frame #13: 0x000000010ffe80b2 Foundation`-[NSBlockOperation main] + 98
    frame #14: 0x000000010ffca774 Foundation`-[__NSOperationInternal _start:] + 645
    frame #15: 0x000000010ffca383 Foundation`__NSOQSchedule_f + 184
    frame #16: 0x0000000112e60614 libdispatch.dylib`_dispatch_client_callout + 8
    frame #17: 0x0000000112e48a1c libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1664
    frame #18: 0x000000010f8841f9 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    frame #19: 0x000000010f845dcb CoreFoundation`__CFRunLoopRun + 2043
    frame #20: 0x000000010f845366 CoreFoundation`CFRunLoopRunSpecific + 470
    frame #21: 0x0000000113d02a3e GraphicsServices`GSEventRunModal + 161
    frame #22: 0x00000001109288c0 UIKit`UIApplicationMain + 1282
    frame #23: 0x000000010f027727 IphoneApplication`main + 135 at AppDelegate.swift:13
    frame #24: 0x0000000112e94145 libdyld.dylib`start + 1
Run Code Online (Sandbox Code Playgroud)

fum*_*007 21

更新(Swift 4.2+)

如果您确实需要Hashable出于某种原因手动实现一致性,请升级到Swift 4.2+以采用新的Hashable协议,该协议为您提供了一个易于使用的Hasher对象,该对象在内部使用精心设计的散列算法.

例如,上面的哈希函数将被转换为

func hash(into hasher: inout Hasher) {
   hasher.combine(id)
   hasher.combine(name)
   hasher.combine(location)
}
Run Code Online (Sandbox Code Playgroud)

更新(Swift 4.1+)

升级到Swift 4.1以获得编译器支持自动合成HashableEquatable一致性!有关更多详细信息,请参阅Swift Evolution提案.


原始答案

是的,这看起来像整数溢出.您可以尝试使用乘法和加法运算符的溢出版本:&*&+.

阅读The Swift Programming Language一书中的更多内容.

  • Swift文档和WWDC会话都是正确的.`hasher.combine(foo)`和`foo.hash(into:&hasher)`是完全等价的; 随意使用您喜欢的任何形式. (2认同)