sortInPlace crashes in release mode (Xcode 7.1B3)

Hi,


My app was working fine, and then I did a minor update of an asset, built it, tested it in Debug Mode, uploaded to TestFlight, and now my testers report a systematic crash.


I built using Xcode 7.1B3


Long story short, a call to sortInPlace now crashes deep inside it:


class CourseEvent : CustomDebugStringConvertible {
    var Date: String = "0"
    <...>
}

var courseArray : [CourseEvent]
<...>
courseArray.sortInPlace {$0.Date <= $1.Date}


Where:

- courseArray indeed is a valid array of CourseEvent objects, which has, among others, a property named "Date". I checked the array is not corrupt, nor empty

- the call doesn't crash in the Debug configuration, only in the Release configuration

- the crash happens on the device as well as the simulator, with no difference that I could see

- the same code didn't crash in an earlier build, though I can't remember which exact version of Xcode I was using (but definitely the Xcode 7 family, since I am using Swift 2.0).


I have a workaround, as the following doesn't crash:


courseArray = courseArray.sort {$0.Date <= $1.Date}


So, is the bug mine, or is there a bug in Swift's sortInPlace? Should I spent the time to reduce it and file a bug report?


Thanks,


JD

Replies

I'm seeing this in several places that I use sortInPlace in my app as well. Works in debug, crashes in release. Invalid address for the fields in the closure.

Submit a bug report. This was preventing me from testing iCloud integration. I will try your suggested workaround and then try to build a simple example and file my own bug report.


Mike

I believe there are some bugs in Swift Compiler's Optimizer around ARC.


To narrow down the cause there are two things you could try.


1. In the Release Build Configuration Optimization Level of the Swift Compiler from the default `Fast [-O]` to `None [-O]` or `Fast, Whole Module Optimization [-O, -whole-module-optimization]`. This build configuration can be found under `Swift Compiler - Code Generation > Optimization Level` or `SWIFT_OPTIMIZATION_LEVEL`


2. In Enable Zombie Objects in the Release Scheme and run on the Simulator. This option can be found by editing the scheme selecting run and going to the Diagonostic tab.


If it's a similar issue to what I've found the workaround is to force a local retain of all objects in the array.

I wouldn't be surprised if the system code does some data manipulation similar to sortInPlace when adding constraints at runtime. I've reproduced a simple example for my bug report. JD's workaround is all I needed to get running without losing optimization elsewhere in the code.


Mike

I'm running into the same problems as you are...
The compiler seems to do some incorrect optimizations and releases objects so the sortInPlace fails, while a x = x.sort is working...


Did you file a bug report? If not, i will!

Same issue here, so /bump.


The one caveat being - sortInPlace is not universally failing for me. It is only in the case where the array that is being sorted is the ONLY reference to the objects it contains.


For example -


//     EXHIBIT A
var allItems: [String : ItemModel] = [] // fill allItems with instances
var activeItems: [ItemModel] = []
activeItems.append( allItems[ "itemid1" ] )
activeItems.append( allItems[ "itemid2" ] )
//  this seems to work fine since we have 2 refs to the items
activeItems.sortInPlace({ $0.numThings > $1.numThings })

//     EXHIBIT B
var otherItems: [ ItemModel ] = []
otherItems.append( ItemModel(string: "data1") )
otherItems.append( ItemModel(string: "data2") )
//  this will crash in Release and not debug since we only have 1 reference to the items
activeItems.sortInPlace({ $0.numThings > $1.numThings })
//  this will work fine as a workaround
let sortedItems = activeItems.sort({ $0.numThings > $1.numThings })


Exhibit A works fine because instances are referenced by something other than the array being sorted in place

Exhibit B crashes in Release only and works in Debug. The workaround of sorting into a destination array seems to work in both modes.

Thank you Tim!


It's an annoying bug....

I'm seeing the same thing, same symptoms as everyone else. I added a log message in my collection item's dealloc method, and confirmed the last item in the array is being deallocated prematurely.


Xcode 7.1 (7B91b)

This seems to be fixed in Xcode 7.2 beta 2.

This works for me - thanks