Swift crash on updating dictionary with a new set repeatedly

Recently we came across a rather peculiar crash on our swift app.


0  OurApp  0x000000010005c0d0 generic specialization <Swift.String with Swift.String : Swift.Hashable in Swift> of Swift._VariantSetStorage.nativeRemoveObjectForKey <A : Swift.Hashable>(inout Swift._VariantSetStorage<A>)(A) -> Swift.Optional<A> (ProductFilterTableViewModel.swift)
1  OurApp  0x00000001000570d4 function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed> of OurApp.ProductFilterTableViewModel.toggleSelectionStateForCellAtIndexPath (OurApp.ProductFilterTableViewModel)(ObjectiveC.NSIndexPath) -> () (ProductFilterTableViewModel.swift:511)
2  OurApp  0x000000010004ef44 @objc OurApp.ProductFilterTableViewModel.handleRadioButtonPressedChanged (OurApp.ProductFilterTableViewModel)(ObjectiveC.UIButton) -> () (ProductFilterTableViewModel.swift:629)


This crash could only be reproduced in release mode and happened when toggling a radio button on and off rapidly.


Eventually we came across the following function that updates a dictionary of selected values keyed by a section into a set:


var selectedElementIDSet: Set<String>
if let storedIDs = selectedElementIDsForSectionType(section.sectionType) {
    selectedElementIDSet = storedIDs//this triggers a copy
} else {
    selectedElementIDSet = []
}
selectedElementIDSet.insert(elementID)
selectedElementIDsByFilterSection.updateValue(selectedElementIDSet, forKey: section.sectionType)


Above we are retrieving the set of storedIDs and copying it over to a new variable. Then we insert the elementID into this set and updated our dictionary with this new instance of the Set. It looks like there is some kind of bug in the Swift compiler causing the Set to release its values while the dictionary is updated.


If we naively change the above code to not copy the set and instead update the original the crash no longer occurs


if var storedIDs = selectedElementIDsForSectionType(section.sectionType) {
    storedIDs.insert(elementID)//no more copying
    selectedElementIDsByFilterSection.updateValue(storedIDs, forKey: section.sectionType)
} else {
    var selectedElementIDSet: Set<String> = [elementID]
    selectedElementIDsByFilterSection.updateValue(selectedElementIDSet, forKey: section.sectionType)
}


Am I doing something wrong here or should this be reported as a bug?


Sidenote: This crash has also come up on a different issue here as well but the fix doesnt apply in this scenario

https://forums.developer.apple.com/message/13362#13362

Am I doing something wrong here or should this be reported as a bug?

You should file a bug about this. Even if this were a problem with your code—which I don't think it is—you shouldn't hear about it via a crash in the release build (-:

Please post your bug number, just for the record.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Eskimo!


Just filed a bug: 21896079

Swift crash on updating dictionary with a new set repeatedly
 
 
Q