简体   繁体   中英

Swift optimization level 'Fastest' breaks sorting of array

I have a really strange issue. I'm sorting an array of NSDictionary objects in my app, but it only works correctly when the app is running from Xcode. As soon as I distribute the app and install & run it on a device, the sorting no longer works.

Here's the code can be run in a playground, with some example NSDictionary objects. The code in the app is the same.

import UIKit

let p1 = NSDictionary(objects: ["Zoe", 32], forKeys: ["name", "age"])
let p2 = NSDictionary(objects: ["Adrian", 54], forKeys: ["name", "age"])
let p3 = NSDictionary(objects: ["Jeff", 23], forKeys: ["name", "age"])
let p4 = NSDictionary(objects: ["", 66], forKeys: ["name", "age"])
let p5 = NSDictionary(objects: [23], forKeys: ["age"])

let persons = [p1,p2,p3,p4,p5]

let sortedPersons = persons.sorted { (p1, p2) -> Bool in
    (p2["name"] as? String) > (p1["name"] as? String)
}

As you can see, sorting in the playground does work correctly. Does anyone know what could be wrong?

Update

I found that the Swift Optimization Level is causing the problem. Setting this to -O (Fastest) will cause the sort to fail. Setting it to -Onone (None) will cause the sort to work properly.
Does anyone have any suggestions on how to change the code, so it will work with -O optimization?

Update 2

I've filed a bug report at Apple. For the time being I'm using an NSSet to sort the array, which seems to be working fine.

Last update

I haven't been able to reproduce this since Xcode 6.1.1

This appears to be down to your naming convention within your sorted closure. Changing (p1, p2) to different names will resolve it. With -Ofastest, the compiler seems to be incorrectly doing 2 things:

1) causing p1 and p2 within the closure to refer to the NSDictionarys themselves rather than the closure parameters

2) cleaning up the references to the NSDictionary objects prematurely, given #1

Change the code so the last section shows:

let sortedPersons = persons.sorted { (d1, d2) -> Bool in
    (d2["name"] as? String) > (d1["name"] as? String)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM