For some reason while implementing an objects hashValue for use in other structures the program crashes. It seems to crash when I attempt to get the hashCode of any string object. It is extending a struct but by time the hashValue is used the field that is accessed is already defined. I stretched this by testing a string such as "TEST" and it still crashes. Integer hashValues such as the id field are fine. Any assistance would be appreciated.
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)
}
StackTrace:
* 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
If you do need to manually implement the Hashable
conformance for some reason, upgrade to Swift 4.2+ to adopt the new Hashable protocol, which gives you an easy-to-use Hasher
object that internally uses a well-designed hashing algorithm.
For example, the above hash function would be transformed into
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(name)
hasher.combine(location)
}
Upgrade to Swift 4.1 to gain compiler support for automatic synthesis of Hashable
and Equatable
conformance! See the Swift Evolution proposal for more details.
Yup, this looks like integer overflow. You can try using the overflow versions of the multiplication and addition operators: &*
and &+
.
Read more in The Swift Programming Language book.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With