Swift app deadlocks when calling NSUserDefaults and referencing UIFont.Weight

Originator:keithbsmiley
Number:rdar://39446389 Date Originated:15-Apr-2018 19:32
Status:Open Resolved:
Product:iOS + SDK Product Version:iOS 11.2 / Xcode 9.2 (9C40b) / Swift 4.1
Classification:Crash/Hang/Data Loss Reproducible:Always
 
Summary:
In Xcode 9.2, if you have an app that references UIFont.Weight, and on the first line of your app you set an `Any` value to NSUserDefaults, the app deadlocks. This seems to be because the bridging to `Any` loads any Objective-C types, which includes loading UIFont.Weight, which reads from defaults, acquiring a lock, as you're trying to write, which also attempts to acquire the same lock.

Steps to Reproduce:
1. In Xcode 9.2 create a new iOS project
2. Add `UserDefaults.standard.set([UIFont.Weight.bold.rawValue], forKey: "foo")` as the first line of `application:didFinishLaunchingWithOptions:`
3. Add a breakpoint on `return true` at the bottom of that function
4. Run the app

Expected Results:
The app runs fine

Actual Results:
The app deadlocks and you never reach your breakpoint.

Version:
iOS 11.2 / Xcode 9.2 (9C40b) / Swift 4.1

Notes:
We haven't been able to reproduce this in Xcode 9.3 / Swift 4.1 / iOS 11.3. We can't tell if this is fixed in Swift, since it seems like the metadata for UIFont.Weight doesn't get loaded immediately when this bridge happens anymore, or if it's fixed in iOS because the call `CGFontDBGetLocal` that ends up causing the deadlock gets called way earlier because some status bar related API end up calling it before application:didFinishLaunchingWithOptions:.

Run the attached project for an example.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!