Swift,从异步块返回值

时间:2014-11-18 13:40:09

标签: ios asynchronous swift

iOS开发很新,我刚刚开始涉足GCD,我已经阅读了几篇关于SO的文章,并查阅了Apple的文档,但是我很难理解如何设置“昂贵”操作的返回值

下面的函数将循环总和100K用户(作为示例),在主线程上执行此操作显然会暂停GUI几秒钟,因此在我的UserList类中,我建议在我的线程上异步执行此块:

let queue = dispatch_queue_create("me.alexsims.user_queue", DISPATCH_QUEUE_CONCURRENT)

public func getUserById(userId: String, completionHandler: (result: User) -> ())
{
    dispatch_async(queue)
    {
        for user in self.users {
            if user.getUserId() == userId
            {
                completionHandler(result: user)
            }
        }
        // Return an empty user object
        completionHandler(result: User())
    }
}

根据我的理解,应该返回result变量,然后我应该能够从我的主线程中访问存储在那里的User()对象

但是,当我返回我的控制器并运行测试时:

var list   = UserList()
var a_user = User()

a_user = list.getUserByID(userId: "xyz", completionHandler: { (result) -> () in
    println(result)
})

这会引发错误Could not find an overload for 'println' that accepts the supplied arguments,我猜这是因为我不在主队列中?所以我试试:

a_user = list.getUserById(userId: "xyz", completionHandler: { (result) -> () in
    dispatch_async(dispatch_get_main_queue()) {
        println(result)
    }
})

但是,我仍然得到同样的错误。我在这做错了什么?

解决 正如Daniel所发现的那样,问题是为list.getUserByID调用提供了可选参数。 将其更改为:

a_user = list.getUserById("abcde", completionHandler: { (result) -> () in
    println(result)
})

println错误消失了。

1 个答案:

答案 0 :(得分:4)

您的Swift类User需要实现Printable协议,以便println可以使用它。

这样的事情:

Class User: Printable {
  let name = "Bob"
  var description: String {
    return "User: \(name)"
  }
}

详细了解Apple post

如果您感到懒惰,请将您的User类作为NSObject的子类,该子类已经实现了Printable协议

修改

快速搜索println错误已转为this up。不知道为什么错误会传递给println,但这是一个修复:

尝试删除函数调用的第一个参数,在Swift中,您不需要键入第一个参数来避免冗余:

a_user = list.getUserById(userId: "xyz...

应该是:

a_user = list.getUserById("xyz...