swift - 异步任务后返回数据

标签 swift

我正在使用库上传图片。该库正在异步工作。

我的功能:

func upload() -> String {
    let imageData:NSData = UIImageJPEGRepresentation(pureImage!, 100)!
    var picture=""
    SRWebClient.POST("http://domain.com/upload.php")
        .data(imageData, fieldName:"image_field", data: ["username":"test","key":"test"])
        .send({(response:AnyObject!, status:Int) -> Void in
            if status == 200 {
                let responseJSON = response! as! Dictionary<String, AnyObject>
                let s_status=responseJSON["status"] as! Int
                if s_status == 1 {
                    picture=responseJSON["picture"] as! String
                    print(picture)
                }
            }
            },failure:{(error:NSError!) -> Void in
                picture=""
        })
    return picture
}

如您所见,我必须返回图片名称。但现在它总是返回空字符串,因为上传过程是异步的。上传完成后如何返回图片名称?

最佳答案

显然,您不能将图片名称作为函数结果返回,除非您想等到异步任务完成,等待会使它再次成为同步任务。

有三种非常常见的方法可以使异步任务交付结果:

  1. 向任务传递回调(如果您需要捕获状态或引用,则可以是回调函数或完成 block )。任务完成后,它会调用回调。在您的情况下,回调可以获取图像名称作为参数,然后回调代码需要决定如何处理它。

  2. 如果任务被封装在一个对象中,允许对象有一个委托(delegate)。任务完成后,将调用委托(delegate)方法。该方法要么获取图像名称作为参数,要么可以从它作为委托(delegate)的对象中查询图像名称(通常您会将对象本身作为参数传递给委托(delegate),这是苹果公司的常见做法和良好的编码风格) .

  3. 发送图像已上传的通知。图片名称可以作为通知的对象;或者封装图像名称和可能的其他属性的一些对象。任何有兴趣知道上传任务何时完成的人都可以注册该通知。

关于上述选项的一些说明:

我会谨慎使用通知。虽然它们易于使用并且在需要通知分布在大型项目中的大量组件时非常有用,但它们很难调试(您无法在调试器中轻松地遵循代码流)并且它们会产生非常低的耦合度(这可能是可取的,也可能不是可取的),但与通知本身有很强的耦合。此外,通知不能返回一个值,以防万一。

委托(delegate)总是一个不错的选择,但它迫使用户创建一个实现委托(delegate)协议(protocol)的类。这通常只有在您不仅需要一个回调方法或者您计划非常频繁地调用委托(delegate)方法时才有用。委托(delegate)非常适合单元测试。

回调就像一个只有一个回调方法的小委托(delegate)。如果您经常在旅途中执行“即发即弃”任务,并且只需要一个回调,在成功和失败的情况下将被调用;并且它只会被调用一次并且不需要回收它,那么回调通常比委托(delegate)更可取。它具有委托(delegate)的所有优点,但更轻量级。

关于swift - 异步任务后返回数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33476778/

相关文章:

ios - 单个 cartfile 为多个目标指定和安装依赖项

swift - 将强制向下转型视为可选永远不会产生 'nil'

ios - 删除 Bridging Header 后从 Interface Builder 拖动时 Xcode 崩溃

ios - 使用 UITableView 和数组无限滚动

swift - 如何在 UITableView 中有条件地分割数据模型?

swift - Swift 中 auto 和 escaping 闭包的区别和目的是什么?

objective-c - 通过 Obj-C 桥接 header 将 sqlite3.h 导入 Swift 项目不起作用

ios - 循环视频 KUDAN AR

ios - 如何以编程方式在我的选项卡栏 Controller 下添加 UIView?

Swiftlint 覆盖与 SPM 相关的项目设置