【问题标题】:Swift ignoring parameter types defined in block signatureSwift忽略块签名中定义的参数类型
【发布时间】:2019-10-31 05:51:02
【问题描述】:

我有下面的代码,编译器很满意:

func CheckPaintExists(colorCode : String, applicationCode : String) {
    let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
    checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
        return (item as! Paint).ColorCode == colorCode 
            && (item as! Paint).ApplicationCode == applicationCode
    })
    checkRequest.includesSubentities = false;

    //managedContext.count(for: ...)do further stuff
}

但是一旦我在块签名中定义了item 类型,我就会在返回行上得到一个错误:

func CheckPaintExists2(colorCode : String, applicationCode : String) {
    let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
    checkRequest.predicate = NSPredicate(block: { (item : Paint?, bindings : NSDictionary?) -> Bool in
        return item.ColorCode == colorCode //*Value of type 'Any?' has no member 'ColorCode'
            && item.ApplicationCode == applicationCode
    })
    checkRequest.includesSubentities = false;

    //managedContext.count(for: ...)do further stuff
}

上面写着Value of type 'Any?' has no member 'ColorCode'。我该如何解决这个问题?为什么它仍然使用块提供的默认 Any 类型?

【问题讨论】:

    标签: swift nspredicate swift-block swift-optionals


    【解决方案1】:

    如果您查看signature 中的NSPredicate.init(block:),您会看到该块接受两个参数并返回一个布尔值:(Any?, [String : Any]?) -&gt; Bool),第一个参数确实是一个Any

    在您的第一个示例中,您强制使用as! 进行强制转换,这就是它起作用的原因(如果类型实际上不是Paint 装箱在Any 中,它会在这里崩溃。您的第二个示例给您一个错误,因为你的类型注释是错误的;编译器期望第一个参数是Any 而不是Paint?;它确实应该在上面的行中给你错误,但它似乎第一次在返回的行中捕获它。

    如果你想安全地打开它应该是:

    func CheckPaintExists(colorCode : String, applicationCode : String) {
        let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
        checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
            guard let paint = item as? Paint else {
               return false
            }
            return paint.ColorCode == colorCode 
                && paint.ApplicationCode == applicationCode
        })
        checkRequest.includesSubentities = false;
    
        //managedContext.count(for: ...)do further stuff
    }
    

    【讨论】:

    • 奇怪的是,当我在项目上点击dot 时,Xcode 自动完成/建议实际上会显示/建议 Paint 属性。这意味着它将 item 视为 Paint 类型。一旦我点击进入放置属性,它就会抱怨。我只是觉得很奇怪。我确实考虑过安全展开item,但我想我肯定知道item 将是Paint 类型,并且安全展开它对我的情况来说似乎很麻烦。他们说swift 的代码比swift 少,我说它恰恰相反。我猜那是另一个 convo 的话题。干杯
    猜你喜欢
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2021-03-07
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多