2016-01-01 38 views
0

我有以下方法,主要使用username参数从后端Parse加载用户的图片。Swift - UIImage和Nil Value

func getProfilePicture(username: String) -> UIImage 
    { 
     var tempImage:UIImage = UIImage(named: "sample-qr-code.png")! 
     let query: PFQuery = PFQuery(className: "_User") 
     query.whereKey("appUsername", equalTo: username) 
     query.findObjectsInBackgroundWithBlock { 
      (objects:[PFObject]?, error:NSError?) -> Void in 
      for object in objects! { 

       let imageFiles = object["ProfilePic"] as! PFFile 

       imageFiles.getDataInBackgroundWithBlock({ 
        (imageData: NSData?, error: NSError?) -> Void in 
        if (error == nil) { 
         tempImage = UIImage(data:imageData!)! 
        } 

       }) 

      } 

     } 
     return tempImage 
    } 

在该方法的第一行,我的理由很简单,它不能为空值分配给tempImage否则它抛出零例外。当上面的代码运行时,它会遍历所有阶段和条件(通过使用打印函数进行日志记录来检测),但返回的图像仍然是sample-qr-code.png,而不是数据库中的那个。有没有从后端抛出错误,该行被执行:

tempImage = UIImage(data:imageData!)! 

有人可以帮我解决这是为什么不显示从后端的画面?我猜测它可能与初始化和范围有关,但不确定。

回答

1

这是因为函数在闭包中的任务完成之前完成的。

您应该让tempImage成为自己的一个属性,并让闭包更新该属性。

class SomeClass { 

    var tempImage: UIImage? 

    func someFuncToGetStuff() { 

     Parse.doParseStuffWithCompletion(fetchedPFFile) -> Void in 

      let myImage = UIImage(data: fetchedPFFile) 
      self.tempImage = myImage 

      } 

    } 

} 
+0

你能否详细说明你在这里的意思......它本身的属性? –

+0

假设函数存在于仍在内存中引用的类中,如果将UIImage设置为该类的属性,那么即使在启动闭包的函数完成后,闭包内的任务也可以访问它。 –

+0

在答案中增加了一个例子,显然你想有条件地做东西(比如如果事情不是零等) –

1

query.findObjectsInBackgroundWithBlock在后台运行。这意味着当你的函数返回时,它会有你最初分配给它的默认图像。

tempImage可以立即重置或被攻击,或者在getProfilePicture方法返回默认图像后立即触发,或最多一秒。

您需要重做如何获取该图像,例如(即通过findObjects:,可能很慢)或通过图像视图出口,并在后台功能成功完成后立即将图像写入图像视图。

+0

这可以使用完成? –

+0

您需要将IBOutlet传递给getProfilePicture方法,或者将imageView属性设置为新创建的UIImage。 –