I wrote this in Xcode 8 Beta 6 (8S201h):
guard let faceMembers = NSFontManager.shared().availableMembers(ofFontFamily: familyName ?? fontName) else { return nil }
And it worked just fine. Now that I've upgraded to Xcode 8 GM Seed (8A218a) Xcode 8 (8A218a), it crashes (EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
).
Using the debugger to narrow it down, I found that something in NSFontManager.availableMembers(ofFontFamily:)
really hates this, since it crashes no matter what I put in there, even with common (definitely installed!) fonts like Helvetica Neue.
(lldb) po NSFontManager.shared()
<NSFontManager: 0x6100000a24c0>
(lldb) po familyName
▿ Optional<String>
- some : "Helvetica Neue"
(lldb) po fontName
"HelveticaNeue"
(lldb) po NSFontManager.shared().availableMembers(ofFontFamily: familyName ?? fontName)
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been returned to the state before expression evaluation.
(lldb) po NSFontManager.shared().availableMembers(ofFontFamily: familyName!)
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been returned to the state before expression evaluation.
(lldb) po NSFontManager.shared().availableMembers(ofFontFamily: "Not a real font?!")
nil
So when I pass it a valid font family name, it crashes... but when I pass it a fake one, it returns nil
.
Is this a problem I can solve, or just an issue with Xcode 8 GM Seed Xcode 8 which will be solved in an SDK update?
After looking through the crash log, I saw this suspiciousness:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libswiftFoundation.dylib 0x0000000107cbb249 _TZFE10FoundationSa26_forceBridgeFromObjectiveCfTCSo7NSArray6resultRGSqGSax___T_ + 153
1 libswiftCore.dylib 0x00000001079031f3 swift_dynamicCast + 1635
2 libswiftCore.dylib 0x000000010790448b _dynamicCastFromExistential(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::TargetMetadata<swift::InProcess> const*, swift::DynamicCastFlags) + 91
3 libswiftCore.dylib 0x0000000107903919 swift_dynamicCast + 3465
4 libswiftFoundation.dylib 0x0000000107d6a348 _TPA__TFFs15_arrayForceCastu0_rFGSax_GSaq__U_FQ_Q0_ + 56
5 libswiftFoundation.dylib 0x0000000107cbbc45 _TFEsPs10Collection3mapurfzFzWx8Iterator7Element_qd__GSaqd___ + 885
6 libswiftFoundation.dylib 0x0000000107cbb4c3 _TFs15_arrayForceCastu0_rFGSax_GSaq__ + 227
7 libswiftFoundation.dylib 0x0000000107cbb7a5 _TZFE10FoundationSa36_unconditionallyBridgeFromObjectiveCfGSqCSo7NSArray_GSax_ + 197
So it seems like it's crashing within Swift-Foundation, in some function called _forceBridgeFromObjectiveC
... not sure if that helps anyone but it does confirm it's within the SDK/runtime.