第二个语句在第一个语句在一个函数中完成之前被调用 [英] Second If statement gets called before first statement finished in one function
问题描述
我有一个函数,其中有2个if语句。代码:
func pictureFromFirebase(loginMethod:Int)
{
如果loginMethod == 0 // FB
{
var profilePic = FBSDKGraphRequest(graphPath:me / picture,parameters:[height:300,width:300,redirect:false],httpMethod:GET)
让profilePicRef = storageRef.child((user?.uid)!+/ profile_pic.jpg)
profilePicRef.data(withMaxSize:1 * 1024 * 1024){data,error in
如果让错误=错误{
//呃 - 哦,发生了一个错误!
} else {
if(data!= nil)
{
print(no need to download image from facebook)
self.profileImage.image = UIImage (data:data!)
}
}
}
if profileImage.image == nil
{
print(从facebook上下载图片)
profilePic?.start(completionHandler:{(_ connection,_ result,_ error) - >无效
if(error == nil)
{
if let dictionary = [String:Any],让data = dictionary [data]为?[String:Any],
让urlPic = data [url] as?String {
if let imageData = NSData(contentsOf:NSURL(string:urlPic)!as URL)
{
let uploadTask = profilePicRef.put(imageData as Data,metadata:nil){
metadata,error in
if(error == nil)
{
let downloadUrl = metadata!.downloadURL
}
else
{
print(图片下载错误 )
}
}
self.profileImage.image = UIImage(data:imageData as Data)
}
}
}
$)
code $ $ $ $ $ $ $ $ $ $ $ $ $只有当这个函数被触发时才会调用:
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
print(called)
if let user = user {
if(activeUser!= user){
let name = user.displayName
self.profileName.text = n ame
self.pictureFromFirebase(loginMethod:0)
}
}
<这是从调试的正常输出,当我已经设置了一个图像,所以不需要从Facebook下载图像:
- 所谓的
- 从脸书下载图片
- 名为
- 从Facebook下载图片
- 无需从脸书下载图片
- 无需从Facebook下载图片
这是从调试的输出,当我删除整个第二条if语句(如果profileImage.image ==零):
- 所谓
-called
- 无需从facebook下载图片
- 无需从Facebook下载图片
从我所能看到的除了该函数被调用两次,这也是错误的,第二个语句在第一个语句执行之前被调用。由于第一个语句在profileImage被设置之前需要一段时间,所以当第二个if语句正在检查该值时它的nil为零。我怎样才能确保这不会再发生?谢谢。
异步方法!你必须等待完成,然后继续下一步。
把第二个块放到第一个完成处理程序中 - 像这样
func pictureFromFirebase(loginMethod:Int)
{
如果loginMethod == 0 // FB
{
var profilePic = FBSDKGraphRequest(graphPath:me / picture,parameters:[height:300,width:300,redirect:false],httpMethod:GET)
let profilePicRef = storageRef。 ($ user.uid)!+/ profile_pic.jpg)
profilePicRef.data(withMaxSize:1 * 1024 * 1024){data,error
if error = error {
//呃 - 哦,发生了一个错误!
//但是我们不需要做任何事情。尝试下载配置文件pic
如果(data!= nil)
{
print(no need to download image from facebook)
self.profileImage .image = UIImage(data:data!)
}
else
{
//这是已经被移动的块
//现在将被执行在两种情况下 -
// 1.下载错误
// 2.无配置文件PIC可用
print(从facebook上下载图片)
profilePic?.start (completionHandler:{(_ connection,_ result,_ error) - >无效
if(error == nil)
{
if let dictionary = result as?[String:Any ],让data = dictionary [data] as?[String:Any],
让urlPic = data [url] as?String {
如果让imageData = NSData(contentsOf:NSURL(string:urlPic)!作为URL)
{
let uploadTask = profilePicRef.put(imageData as Data,元数据:nil){
元数据,错误$ b $ if(error == nil)
{
let downloadUrl = metadata!.downloadURL
}
else
{
print(下载图片时出错)
}
}
self.profileImage.image = UIImage(data:imageData as Data)
}
}
}
})
}
$ b code $ pre
I have one function with 2 if statements inside it. Code:
func pictureFromFirebase(loginMethod: Int)
{
if loginMethod == 0 //FB
{
var profilePic = FBSDKGraphRequest(graphPath: "me/picture", parameters: ["height":300, "width":300, "redirect":false], httpMethod: "GET")
let profilePicRef = storageRef.child((user?.uid)!+"/profile_pic.jpg")
profilePicRef.data(withMaxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
// Uh-oh, an error occurred!
} else {
if (data != nil)
{
print("no need to download image from facebook")
self.profileImage.image = UIImage (data: data!)
}
}
}
if profileImage.image == nil
{
print("downloading image from facebook")
profilePic?.start(completionHandler: {(_ connection, _ result, _ error) -> Void in
if (error == nil)
{
if let dictionary = result as? [String:Any], let data = dictionary["data"] as? [String:Any],
let urlPic = data["url"] as? String {
if let imageData = NSData(contentsOf: NSURL(string: urlPic)! as URL)
{
let uploadTask = profilePicRef.put(imageData as Data, metadata: nil){
metadata, error in
if (error == nil)
{
let downloadUrl = metadata!.downloadURL
}
else
{
print("error in downloading image")
}
}
self.profileImage.image = UIImage(data: imageData as Data)
}
}
}
})
}
}
}
It gets only called when this function is triggered:
FIRAuth.auth()?.addStateDidChangeListener() { (auth, user) in
print("called")
if let user = user {
if(activeUser != user){
let name = user.displayName
self.profileName.text = name
self.pictureFromFirebase(loginMethod: 0)
}
}
This is the normal output from the debug, when I already have set an image so downloading an image from Facebook is not needed:
-called
-downloading image from facebook
-called
-downloading image from facebook
-no need to download image from facebook
-no need to download image from Facebook
This is the output from the debug when I remove the whole second if statement (if profileImage.image == nil):
-called
-called
-no need to download image from facebook
-no need to download image from Facebook
From what I can see, apart that the function are called twice which is also wrong, the second statement gets called before the first statement is executed. Since the first statement takes a while before the profileImage is set, its nil when the second if statement is checking this value. How can I make sure this won't happen anymore? Thank you.
解决方案 Asynchronous methods! You have to wait for the completion before you move on to the next step.
Put the second block within the first completion handler - like this
func pictureFromFirebase(loginMethod: Int)
{
if loginMethod == 0 //FB
{
var profilePic = FBSDKGraphRequest(graphPath: "me/picture", parameters: ["height":300, "width":300, "redirect":false], httpMethod: "GET")
let profilePicRef = storageRef.child((user?.uid)!+"/profile_pic.jpg")
profilePicRef.data(withMaxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
// Uh-oh, an error occurred!
// but we don't need to do anything yet. Try to download the profile pic
}
if (data != nil)
{
print("no need to download image from facebook")
self.profileImage.image = UIImage (data: data!)
}
else
{
// THIS IS THE BLOCK THAT HAS BEEN MOVED
// WHICH WILL NOW BE EXECUTED IN TWO CONDITIONS -
// 1. AN ERROR IN THE DOWNLOAD
// 2. NO PROFILE PIC AVAILABLE
print("downloading image from facebook")
profilePic?.start(completionHandler: {(_ connection, _ result, _ error) -> Void in
if (error == nil)
{
if let dictionary = result as? [String:Any], let data = dictionary["data"] as? [String:Any],
let urlPic = data["url"] as? String {
if let imageData = NSData(contentsOf: NSURL(string: urlPic)! as URL)
{
let uploadTask = profilePicRef.put(imageData as Data, metadata: nil){
metadata, error in
if (error == nil)
{
let downloadUrl = metadata!.downloadURL
}
else
{
print("error in downloading image")
}
}
self.profileImage.image = UIImage(data: imageData as Data)
}
}
}
})
}
}
}
}
这篇关于第二个语句在第一个语句在一个函数中完成之前被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!