二元运算符'>'不能应用于两个'String ?!'操作数

问题描述:

所以我有一个项目,建立好。但母鸡我想将其封存洒在这行代码此错误:二元运算符'>'不能应用于两个'String ?!'操作数

let pred = NSPredicate(format: "%K in %@", "categoryID", selectedCategoryIDs!) 
let selectedAlmanacEntries = almanacEntries.filter { pred.evaluate(with: $0) }.sorted(by: { ($0 as AnyObject).title > ($1 as AnyObject).title }) 

此之前没有被(早期版本)的问题。 已尝试重新启动Xcode并清理项目。 任何提示赞赏。

(Xcode中8,斯威夫特3)

?!是一个真正伟大的建筑,不是吗?当你在错误信息中看到它时,完美地总结出反应。

无论如何,在Swift中,您最好转换为这些对象应该属于的适当类型,而不是AnyObject。如果你必须使用duck类型,那么你应该知道Swift每次调用AnyObject的方法时,它都会获得一定的选择性,因为Swift无法验证对象实际上是否响应该消息。所以你将不得不处理可选项。

另一个问题是,由于框架中存在多个类,其属性名为title,因此Swift无法知道要使用哪一个类。其中一些签名不同;例如,NSButton具有被分类为String一个title属性,NSStatusItem具有被分类为String?一个title属性,NSWindowTab具有被分类为String!一个title属性。编译器选择哪一个是抽奖的一点点运气,这就是为什么随机机会可以使其从编译到编译的行为不同。所以你需要告诉它什么类型的期望来帮助编译器。

所以,像这样可以工作:

let selectedAlmanacEntries = almanacEntries.filter { pred.evaluate(with: $0) }.sorted(by: { 
    guard let first: String = ($0 as AnyObject).title else { return false } 
    guard let second: String = ($1 as AnyObject).title else { return true } 

    return first > second 
}) 

或者,如果你的心脏上长的单行设置为原文:

let selectedAlmanacEntries = almanacEntries.filter { pred.evaluate(with: $0) }.sorted(by: { (($0 as AnyObject).title as String?) ?? "" > (($1 as AnyObject).title as String?) ?? "" }) 

我真的建议铸造但实际的类型,而不是。