使用AlamoFire框架后,我注意到completionHandler在主线程上运行.我想知道下面的代码是否是在完成处理程序中创建核心数据导入任务的良好实践:

Alamofire.request(.GET, "http://myWebSite.com", parameters: parameters)
            .responseJSON(options: .MutableContainers) { (_, _, JSON, error) -> Void in
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { () -> Void in
                    if let err = error{
                        println("Error:\(error)")
                        return;
                    }

                    if let jsonArray = JSON as? [NSArray]{                       
                        let importer = CDImporter(incomingArray: jsonArray entity: "Artist", map: artistEntityMap);

                    }
                });
            }

推荐答案

这是一个非常好的问题.你的方法完全正确.然而,Alamofire实际上可以帮助您进一步简化这一过程.

您的示例代码分派队列细分

在示例代码中,您正在以下调度队列之间 skip :

  1. NSURLSession调度队列
  2. 用于验证和序列化程序处理的TaskDelegate调度队列
  3. 用于调用完成处理程序的主调度队列
  4. 用于JSON处理的高优先级队列
  5. 用于更新用户界面的主调度队列(如有必要)

正如你所见,你到处都是.让我们来看看另一种利用Alamofire内部强大功能的方法.

Alamofire响应调度队列

Alamofire在其自身的低级别处理中内置了一种最佳方法.最终被所有自定义响应序列化程序调用的单个response方法支持自定义调度队列(如果您 Select 使用它).

虽然GCD在调度队列之间的跳转非常出色,但您希望避免跳转到繁忙的队列(例如主线程).通过消除在异步处理中间的主线程的跳转,可以极大地加快速度.下面的示例演示了如何直接使用Alamofire逻辑实现这一点.

阿拉莫菲尔1号.十、

let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)

let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
    queue: queue,
    serializer: Request.JSONResponseSerializer(options: .AllowFragments),
    completionHandler: { _, _, JSON, _ in

        // You are now running on the concurrent `queue` you created earlier.
        println("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")

        // Validate your JSON response and convert into model objects if necessary
        println(JSON)

        // To update anything on the main thread, just jump back on like so.
        dispatch_async(dispatch_get_main_queue()) {
            println("Am I back on the main thread: \(NSThread.isMainThread())")
        }
    }
)

阿拉莫菲尔3号.x(Swift 2.2和2.3)

let queue = dispatch_queue_create("com.cnoon.manager-response-queue", DISPATCH_QUEUE_CONCURRENT)

let request = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
request.response(
    queue: queue,
    responseSerializer: Request.JSONResponseSerializer(options: .AllowFragments),
    completionHandler: { response in
        // You are now running on the concurrent `queue` you created earlier.
        print("Parsing JSON on thread: \(NSThread.currentThread()) is main thread: \(NSThread.isMainThread())")

        // Validate your JSON response and convert into model objects if necessary
        print(response.result.value)

        // To update anything on the main thread, just jump back on like so.
        dispatch_async(dispatch_get_main_queue()) {
            print("Am I back on the main thread: \(NSThread.isMainThread())")
        }
    }
)

阿拉莫菲尔4号.x(Swift 3)

let queue = DispatchQueue(label: "com.cnoon.response-queue", qos: .utility, attributes: [.concurrent])

Alamofire.request("http://httpbin.org/get", parameters: ["foo": "bar"])
    .response(
        queue: queue,
        responseSerializer: DataRequest.jsonResponseSerializer(),
        completionHandler: { response in
            // You are now running on the concurrent `queue` you created earlier.
            print("Parsing JSON on thread: \(Thread.current) is main thread: \(Thread.isMainThread)")

            // Validate your JSON response and convert into model objects if necessary
            print(response.result.value)

            // To update anything on the main thread, just jump back on like so.
            DispatchQueue.main.async {
                print("Am I back on the main thread: \(Thread.isMainThread)")
            }
        }
    )

阿拉莫菲尔调度队列故障

下面是这种方法涉及的不同调度队列的分类.

  1. NSURLSession调度队列
  2. 用于验证和序列化程序处理的TaskDelegate调度队列
  3. 用于JSON处理的自定义管理器并发调度队列
  4. 用于更新用户界面的主调度队列(如有必要)

总结

通过消除返回主调度队列的第一跳,您消除了一个潜在的瓶颈,并且使整个请求和处理变得异步.令人惊叹的

尽管如此,我还是要强调,熟悉Alamofire的工作原理是多么重要.你永远不知道什么时候你能找到真正能帮助你改进自己代码的东西.

Swift相关问答推荐

数据不会被ARC删除在swift'

如何使用swift宏生成一个带有关联值的枚举?

SwiftUI—如何识别单词并获取视觉中的位置

体积单位从夸脱转换为杯似乎关闭了

音频播放器无法播放URL音频(操作系统状态错误2003334207.)

同时具有每个文本的标识符的文本组的可扩展性标识符

从SwiftUI使用UIPageView时,同一页面连续显示两次的问题

可以';t在标记为@Observable的类上使用属性包装

SwiftUI 中的同一个 ForEach 中是否可以有 2 个数组?

有没有办法让文本字段以不同的 colored颜色 显示而不影响半透明背景?

SwiftUI 无法在实时活动中显示 SpriteView

在 RealmSwift 中表示范围值?

如何在 SwiftUI 中将图像传递到 2 个视图

SwiftUI 视图的默认成员初始化器 VS 自定义初始化器

如何在 SwiftUI 中正确实现Collection 夹?

当我必须在 Swift 中的类、 struct 和枚举之间进行 Select 时,我应该如何推理?

FCM 后台通知在 iOS 中不起作用

使用 Swift 以编程方式自定义 UITableViewCell

判断用户是否登录到 iCloud?Swift /iOS

Swift 5 秒后关闭 UIAlertView