Swift 3错误:[_SwiftValue pointSize]未识别的选择器发送到实例

33

我刚将我们的项目迁移到Swift 3,发现由于一个问题导致很多崩溃:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue pointSize]: unrecognized selector sent to instance

该错误的原因是调用了以下代码:

[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:context:]

我注意到如果将String转换为NSString并调用boundingRectWithSize,会抛出该错误。似乎在许多其他部分也发生了类似的情况,例如如果我在storyboard中发送视图控制器标题,它也会抛出相同的错误。

有人遇到相同的问题吗?

复现问题的步骤:

在Xcode 8中创建一个新的Swift 3项目,并在viewDidLoad中添加以下行:

let attributes: [String: AnyObject?] = [
            NSFontAttributeName: UIFont.systemFont(ofSize: 14)
        ]
    let boundingRect = ("hello" as NSString).boundingRect(with: CGSize(width: 100, height: 100), options: .usesLineFragmentOrigin, attributes: attributes, context: nil)

但正如我所说,它在许多其他地方都会崩溃,因为似乎UIKit在许多部分内部使用了这个方法。


请展示您引起问题的代码以及相关部分。 - OOPer
似乎与NSString的内部实现有关。 - 3lvis
我遇到了同样的崩溃,但是是在这里:(textLabel.text! as NSString).size(attributes: fontAttributes)我尝试了使用NSMutableString,将字符串附加到它上面等等,但仍然会崩溃。毫无疑问,这是苹果的问题。非常非常糟糕。无法迁移。 - ullstrm
类似的崩溃。苹果在干什么!(不,我没有强制解包“doing” ;) ) - Koushik Ravikumar
4个回答

33

如果我使用您的测试代码,但让attributes的数据类型保持默认值,则不会崩溃。也就是说:

let attributes = [NSFontAttributeName: UIFont.systemFont(ofSize: 14)]

通过Option-clicking在变量上可以看到它是[String : UIFont]

进一步测试表明它与可选对象有关;[String: AnyObject]似乎可以正常工作。

编辑:在所有这些之后,我决定阅读文档,文档中建议使用[String: Any]。 :)


29
很棒的发现,Phillip。这里有一点需要注意,如果有人正在使用自定义字体,则应该将其解包:UIFont(name: UIFont.lightFontName(), size: 14)! - Leonid
2
是的, 因为 UIFont(name: size:) 返回一个 UIFont?. 在创建字典条目之前, 您需要将其解包...但最好不要使用 ! (除非崩溃是必需的)。 - Phillip Mills
2
我遇到了一个非常相似的颜色问题。 NSForegroundColorAttributeName 使用可选的 NSColor 进行设置(是的,在 macOS 上使用 NS-)。在3.0之前,这将导致错误。对于一些新的可选处理方式并不是很满意。 - WCByrne
我在 someLabel.sizeToFit() 中遇到了相同的错误。正如我们在我的和Leonid的情况中所看到的,我们想要获取字符串的矩形。因此,我们可以假设苹果公司希望我们始终使用非可选字体来进行计算。 - Mantas Laurinavičius

2
以下内容解决了我的问题:

let attributes: [String: UIFont] = [NSFontAttributeName: UIFont.systemFont(ofSize: 14)]

0
func attributedString(firstText : String, amount : String, fontSize : CGFloat, color : UIColor) -> NSAttributedString {

    let attrDict = [ NSFontAttributeName : UIFont(name: fontRegular, size: CGFloat(fontSize/2))!,
                    NSForegroundColorAttributeName : UIColor.darkGray] as [String : AnyObject]
    let iconString = NSMutableAttributedString(string: firstText, attributes: attrDict)

    let attrDict1 = [ NSFontAttributeName : UIFont(name: fontRegular, size: CGFloat(fontSize))!,
                     NSForegroundColorAttributeName : color] as [String : AnyObject]
    let amountString = NSMutableAttributedString(string: amount, attributes: attrDict1)

    iconString.append(amountString)
    return iconString
}

并像这样调用

lblBalanceAmount.attributedText = self.attributedString(firstText: "我的余额", amount: "500", fontSize: newFontSize, color : UIColor(red: 41/255.0, green: 192/255.0, blue: 42/255.0, alpha: 1.0))


0

这是因为您以错误的方式设置了字体。我正在尝试弄清楚为什么会失败,但如果您不想使用特定的字体大小,这是解决方案。

let font: UIFont = .body

let attributes: [NSAttributedString.Key : Any] = [
    .font: UIFont.systemFont(ofSize: font.pointSize)
]
pointSize将提供字体类型的大小。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接