我是在Xcode 8 Beta 6(8S201h)中写的:
guard let faceMembers = NSFontManager.shared().availableMembers(ofFontFamily: familyName ?? fontName) else { return nil }
它运作得很好。现在我已升级到 Xcode 8 GM Seed(8A218a) Xcode 8(8A218a),它崩溃了(EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
)。
使用调试器缩小范围,我发现NSFontManager.availableMembers(ofFontFamily:)
中的某些东西真的很讨厌这个,因为它无论我放在那里都会崩溃,即使是像Helvetica Neue这样的常见(明确安装!)字体。< / p>
(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
因此,当我传递一个有效的字体系列名称时,它会崩溃......但是当我将它传递给假名时,它会返回nil
。
这是一个我可以解决的问题,还是
浏览崩溃日志后,我看到了这种可疑:
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
所以看起来它在Swift-Foundation中崩溃,在一些名为_forceBridgeFromObjectiveC
的函数中......不确定这是否对任何人有帮助,但它确实在SDK /运行时内确认了它
答案 0 :(得分:2)
在此期间我能弄清楚如何解决这个问题的唯一方法是在objective-c类中创建一个静态方法。然后我将标头导入我的桥接头并从Swift 3调用静态方法,它在那里工作正常。
希望这有助于您度过这些困难时期!
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
@interface WorkAround : NSObject
+ (NSArray *)typefacesForFontFamily:(NSString *)family;
@end
#import "WorkAround.h"
@implementation WorkAround
/// Returns an array of arrays, or nil, that contain information about
/// each typeface found for the specified font family.
+ (NSArray *)typefacesForFontFamily:(nonnull NSString *)family {
NSFontManager *fontManager = [NSFontManager sharedFontManager];
return [fontManager availableMembersOfFontFamily:family];
}
@end
答案 1 :(得分:1)
Joseph E。的回答是一个很好的起点。然而,为了让它在Swift 3,Xcode 8(8A218a)中运行,我不得不采用不同的方法......
确保将语言更改为(目标C)。重要的是你这样做,因为它看起来you cannot directly create an objective c m files?,即使有这样做的选项。
FontManager.h
#import <Cocoa/Cocoa.h>
@interface FontManager : NSFontManager
NS_ASSUME_NONNULL_BEGIN
+ (NSArray *)typefacesForFontFamily:(NSString *)family;
NS_ASSUME_NONNULL_END
@end
FontManager.m
#import "FontManager.h"
@implementation FontManager
NS_ASSUME_NONNULL_BEGIN
+ (NSArray *)typefacesForFontFamily:(nonnull NSString *)family {
NSFontManager *fontManager = [self sharedFontManager];
return [fontManager availableMembersOfFontFamily:family];
}
NS_ASSUME_NONNULL_END
@end
桥接-header.h
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "FontManager.h"
Swift 3项目中的用法
if let fontMembers = FontManager.typefaces(forFontFamily: "Arial") as? [[Any]] { }