我对这个Swift功能有问题,虽然我确信解决方案相当简单,但我无法弄清楚出了什么问题。这是代码:
static func isArtist(user:FIRUser) -> Bool? {
var artist: Bool?
database.child("users").child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
artist = true //retrieves bool, simplified for example
}) { (error) in
print("isArtist - data could not be retrieved - EXCEPTION: " + error.localizedDescription)
}
return artist
}
该函数每次返回nil
,逻辑上我认为它会返回true
。这是嵌套函数的问题吗?如何在嵌套函数中返回内容?数据库是Swift Firebase SDK的实现,如果没有可以检索到这样的对象,该函数应该只返回nil(对于这个例子,如果artist
是nil)。感谢。
答案 0 :(得分:2)
使用completionBlock:
来处理您的情况,这是因为您已将nil
变量声明为artist
,并且它已归结为optional
需要一些时间从任何后端(异步调用)检索数据,从而在您从数据库中检索某些值之前执行return artist
: -
使用: -
static func isArtist(user:FIRUser, completionBlock : ((isArtistBool : Bool)-> Void)) {
database.child("users").child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
completionBlock(isArtistBool : true) //returns Bool in completionHnadler
}) { (error) in
print("isArtist - data could not be retrieved - EXCEPTION: " + error.localizedDescription)
}
}
当您调用函数isArtist
时: -
isArtist(FIRAuth.auth()!.currentUser, completionBlock : {(isArtistBool) in
//Will return `isArtistBool` in completionHandler
..//rest of the code
})
答案 1 :(得分:0)
请记住,你正在以异步方式获取艺术家的价值。这意味着数据可能在不久的将来可用,但不确定何时。所以,这个异步函数在后台线程中运行,程序继续执行,因此返回nil。
database.child("users").child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
// this is asynchronous block. snapshot is available in near future.
})
所以代替return
使用完成块:
database.child("users").child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
completionBlock(isArtistBool : true)
})
是的,不要忘记删除-> Bool
形式的函数,当你使用completionBlock
时不需要它。
使用完成块时,您的功能签名将如下所示:
isArtist(user: FIRUser, completionBlock: () -> FIRUser)) {
}
您可以将此功能称为:
SomeClass.isArtist(user: FIRUser, completionBlock: () -> FIRUser){
// your user is available here after the value is fetched from firebase.
}
我希望这会有所帮助。