【问题标题】:Completion closure within a closure闭包内的完成闭包
【发布时间】:2015-08-21 13:42:28
【问题描述】:

刚刚开始从 Obj-C 学习 Swift - 这是我不理解的简单内容:

 class func queryForAllUsersWithCallback(completion: (users :[User]?, error :NSError?) ->()) {

        var query = PFQuery(className:User.parseClassName())
        query.findObjectsInBackgroundWithBlock ({
            (objects:[AnyObject]?, error: NSError?) in

            completion(users: objects, error: error);
        })
    }

给我一​​个编译器错误:

 Cannot invoke 'findObjectsInBackgroundWithBlock' with an argument list of type '(([AnyObject]?, NSError?) -> _)'

如果我注释掉这一行:

 completion(users: objects, error: error);

错误消失了,因此警告具有误导性。

【问题讨论】:

    标签: swift


    【解决方案1】:

    completionUser 的数组作为其第一个参数,而objectsAnyObject 的数组。无法保证 objects 中的内容是正确的类型(编译器知道的可能是各种类型的杂乱无章的集合),所以它不会编译。

    如果你做一个条件转换它应该编译,即:

     completion(users: objects as? [User], error: error)
    

    注意,这将在运行时检查objects 中的每个元素是否确实属于正确的类型。如果其中任何一个不是,则整个数组在传递给完成处理程序时将是nil。这将编译,因为参数是可选的,但可能会非常令人惊讶/无声地失败,甚至更糟,崩溃,因为在 completion 内部的某个地方可能假设它 不是 nil,所以它可以得到强制解包。

    因此,您可能希望在其中进行一些错误处理:

    if let users = objects as? [User] {
        completion(users: users, error: error)
    }
    else {
        // log or fatalError or something
    }
    

    (抱歉,如果上述某些语法不太正确,我没有测试代码,因为您的 sn-p 不可重现/独立)

    【讨论】:

      【解决方案2】:

      您只需要将对象转换为用户:

       completion(users: objects as? [User], error: error)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-14
        • 2016-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-12
        • 2012-02-06
        相关资源
        最近更新 更多