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

时间:2017-09-04 20:05:40

标签: swift

所以我有一个项目,建立良好。但是,我想存档它会在这行代码中抛出此错误:

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,Swift 3)

2 个答案:

答案 0 :(得分:2)

?!是一个非常棒的建筑,不是吗?只要您在错误消息中看到它,就可以完美地总结反应。

无论如何,在Swift中,你可能最好不要使用这些对象应该属于的适当类型而不是AnyObject。如果你必须躲避类型,那么你应该知道每次Swift在AnyObject上调用一个方法时,由于Swift无法验证对象是否实际响应了该消息,因此它获得了一个可选级别。所以你必须处理选项。

另一个问题是,由于框架中存在多个具有名为title的属性的类,因此Swift无法知道使用哪个类。其中一些人有不同的签名;例如,NSButton具有title属性,其类型为StringNSStatusItem具有title属性,其类型为String?,并且NSWindowTab具有title属性,其类型为String!。编译器选择哪一个是抽奖的一点运气,这就是为什么随机机会可以使它在编译和编译之间表现不同的原因。因此,您需要通过告诉它预期的类型来帮助编译器。

所以,这样的事情可以起作用:

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?) ?? "" })

我确实建议转换为实际类型。

答案 1 :(得分:0)

雨燕5

您可以通过这种方式简单地包装可选内容

let selectedAlmanacEntries = selectedAlmanacEntries.sorted {
    var isSorted = false
    if let first = $0.title, let second = $1.title {
        isSorted = first < second
    }
    return isSorted
}