第二个语句在第一个语句在一个函数中完成之前被调用 [英] Second If statement gets called before first statement finished in one function

查看:285
本文介绍了第二个语句在第一个语句在一个函数中完成之前被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,其中有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆