将sharedLoader函数转换为普通函数

时间:2015-06-23 01:19:29

标签: ios xcode swift asynchronous sync

我有一个imageLoader函数,可以在其他代码继续运行时加载图像。现在我希望在所有其他代码继续运行之前先运行相同的函数。

这是功能:

//调用函数

    ImageLoader.sharedLoader.imageForUrl(urlstring as String, completionHandler:{(image: UIImage?, url: String) in

        self.productImageView.image = image!

    })

//函数本身

func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in
        var data: NSData? = self.cache.objectForKey(urlString) as? NSData

        if let goodData = data {
            let image = UIImage(data: goodData)
            dispatch_async(dispatch_get_main_queue(), {() in
                completionHandler(image: image, url: urlString)
            })
            return
        }

        var downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: {(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
            if (error != nil) {
                completionHandler(image: nil, url: urlString)
                return
            }

            if data != nil {
                let image = UIImage(data: data)
                self.cache.setObject(data, forKey: urlString)
                dispatch_async(dispatch_get_main_queue(), {() in
                    completionHandler(image: image, url: urlString)
                })
                return
            }

        })
        downloadTask.resume()
    })

}

如何将此int转换为执行相同但正在同步的正常函数

1 个答案:

答案 0 :(得分:2)

我刚刚快速创建了一个函数,它将一个async函数与一个处理程序作为参数并返回结果同步,但要注意:API的异步方法是这样的,原因可能很长,因此应该在后台队列上运行,不要阻塞主队列。无论如何这里是一个带有例子的函数:

func async(handler: Int -> Void) {
    dispatch_async(dispatch_queue_create("AsyncQueue", DISPATCH_QUEUE_SERIAL)) {

        NSThread.sleepForTimeInterval(1)
        handler(3)
    }
}

func syncFromAsync<R>(async: (handler: R -> Void) -> Void) -> R {
    let group = dispatch_group_create()
    var result : R!

    func handler(r : R) {
        result = r
        dispatch_group_leave(group)
    }

    dispatch_group_enter(group)
    async(handler: handler)
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER)

    return result
}

print(syncFromAsync(async))

基本上你创建一个dispatch_group并输入它,提供一个处理程序,你可以在其中保留dispatch_group并等待该组离开。 Swift泛型与此非常吻合。

有关其工作原理的更多细节:

创建一个可以输入或离开的调度组,我们也可以通过调用dispatch_group_wait等待调度组为空。

在我的函数中,结果类型是R,它也是处理程序接受的类型。我正在声明一个函数作为我的处理程序,就像异步函数的任何其他处理程序一样,但它不是对结果执行某些操作,而是将其存储在可选的result中,然后给出该组的信号离开,这将恢复我们的等待命令。

所以我们进入组,告诉异步函数用处理程序做它的事情,然后等到它完成,而我们知道在调用处理程序并且组因此离开时它已经完成。