Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift hashValue crashes application

Tags:

string

swift

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
like image 721
kdgwill Avatar asked Aug 26 '15 18:08

kdgwill


1 Answers

Update (Swift 4.2+)

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)
}

Update (Swift 4.1+)

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.


Original Answer

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.

like image 157
fumoboy007 Avatar answered Nov 05 '22 22:11

fumoboy007