Risposta da @ Abrax5 è eccellente. Volevo solo aggiungere la mia esperienza con questo problema e non poteva inserirla in un commento:
Per quanto posso dire, questo errore viene generato solo al primo tentativo fallito di inizializzare un NSFont
con un nome di font che è non disponibile. Gli inizializzatori NSFont
sono disponibili e restituiscono nil
in questo caso, in cui si ha l'opportunità di fare qualcosa al riguardo.
È possibile controllare se un carattere da un dato nome è disponibile utilizzando:
NSFontDescriptor(fontAttributes: [NSFontNameAttribute: "<font name>"]).matchingFontDescriptorWithMandatoryKeys([NSFontNameAttribute]) != nil
Purtroppo, questo solleva anche l'errore! Il seguente metodo non lo fa, ma è sconsigliata:
let fontDescr = NSFontDescriptor(fontAttributes: [NSFontNameAttribute: "<font name>"])
let isAvailable = NSFontManager.sharedFontManager().availableFontNamesMatchingFontDescriptor(fontDescr)?.count ?? 0 > 0
Quindi l'unico modo che ho trovato di verificare la disponibilità di un tipo di carattere di un nome senza sollevare tale errore è la seguente:
public extension NSFont {
private static let availableFonts = (NSFontManager.sharedFontManager().availableFonts as? [String]).map { Set($0) }
public class func available(fontName: String) -> Bool {
return NSFont.availableFonts?.contains(fontName) ?? false
}
}
Per esempio:
NSFont.available("Georgia") //--> true
NSFont.available("WTF?") //--> false
(probabilmente sono eccessivamente prudente con quella costante opzionale lì e se siete così inclinato è possibile convertire il restituita [AnyObject]
utilizzando as! [String]
...)
Si noti che, per motivi di efficienza, questo non verrà aggiornato fino a quando l'app non viene riavviata, vale a dire qualsiasi font installato durante l'esecuzione dell'app non verrà confrontato. Se questo è un problema importante per la vostra applicazione particolare, basta girare la costante in una proprietà calcolata:
public extension NSFont {
private static var allAvailable: Set<String>? {
return (NSFontManager.sharedFontManager().availableFonts as? [String]).map { Set($0) }
}
private static let allAvailableAtStart = allAvailable
public class func available(fontName: String) -> Bool {
return NSFont.allAvailable?.contains(fontName) ?? false
}
public class func availableAtStart(fontName: String) -> Bool {
return NSFont.allAvailableAtStart?.contains(fontName) ?? false
}
}
Sulla mia macchina available(:)
prende 0.006s
. Naturalmente, availableAtStart(:)
praticamente non ha tempo su tutti tranne la prima chiamata ...
Hmm .. Avevo provato questo ma non ha funzionato. A proposito, il problema rimane ancora ...: S –