小编典典

iOS-Swift-返回异步检索值的函数

swift

所以我有一个来自Parse的PFFile对象,并且我试图创建一个函数来检索该PFFile的UIImage表示并将其返回。就像是:

func imageFromFile(file: PFFile) -> UIImage? {
    var image: UIImage?

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

    return image
}

但是,这里的问题很明显。我每次都会得到nil,因为getDataInBackroundWithBlock函数是异步的。有什么方法可以等到检索到UIImage之后再返回image变量?我不知道在这种情况下使用同步getData()是否有效。


阅读 307

收藏
2020-07-07

共1个答案

小编典典

是的,可以这样做。它称为a
closure,或更常见的是a
callback。A callback本质上是一个可以在其他函数中用作参数的函数。参数的语法是

functionName: (arg0, arg1, arg2, ...) -> ReturnType

ReturnType通常是Void。就您而言,您可以使用

result: (image: UIImage?) -> Void

调用带有一个回调的函数的语法是

function(arg0, arg1, arg2, ...){(callbackArguments) -> CallbackReturnType in
    //code
}

并且使用多个回调调用函数的语法是(缩进以便于阅读)

function(
    arg0, 
    arg1,
    arg2,
    {(cb1Args) -> CB1Return in /*code*/},
    {(cb2Args) -> CB2Return in /*code*/},
    {(cb3Args) -> CB3Return in /*code*/}
)

如果函数对函数进行转义(在函数返回后调用),则必须在参数类型之前添加@escaping

您将要使用一个单个回调,该回调将在函数返回后被调用并包含UIImage?为结果。

因此,您的代码可能看起来像这样

func imageFromFile(file: PFFile, result: @escaping (image: UIImage?) -> Void){
    var image: UIImage?

    file.getDataInBackgroundWithBlock() { (data: NSData?, error: NSError?) -> Void in
        //this should be 'error == nil' instead of 'error != nil'. We want
        //to make sure that there is no error (error == nil) before creating 
        //the image
        if error == nil {
            image = UIImage(data: data!)
            result(image: image)
        }
        else{
            //callback nil so the app does not pause infinitely if 
            //the error != nil
            result(image: nil)
        }
    }
}

调用它,您可以简单地使用

imageFromFile(myPFFile){(image: UIImage?) -> Void in
    //use the image that was just retrieved
}
2020-07-07