[swift]追加在阵列中的图像序列中

发布时间: 2017/3/6 23:34:32
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我想要下载后序列添加图像数组中。我下载一个接一个后追加在阵列中的图像,但它们并非在序列中。请任何一个能告诉我什么是最好的方式做到这一点。

var queue: NSOperationQueue = {
    let _queue = NSOperationQueue()
    _queue.maxConcurrentOperationCount = 4
    return _queue
}()

var imageArrayNsData : [NSData] = []

let session = NSURLSession.sharedSession()

@IBAction func didClickOnStart(sender: AnyObject) {

    queue.cancelAllOperations()

    let completionOperation = NSBlockOperation() {
        print("all done")
    }

    for (index, imageURL) in imageURLs.enumerate() {
        let operation = ImageNetworkOperation(session: session, urlString: imageURL) { image, response, error in

            let dtA : NSData = NSData(data: UIImageJPEGRepresentation(image!, 0.75)!)
            self.imageArrayNsData.append(dtA)
            print("JPEG download\(index)")
        }

        completionOperation.addDependency(operation)
        queue.addOperation(operation)
    }

    NSOperationQueue.mainQueue().addOperation(completionOperation)        
}

结果输出︰

JPEG download0
JPEG download2
JPEG download1
JPEG download3
所做的一切

解决方法 1:

你应该改变你的模型,这样没关系什么顺序下载图像。例如,你有你的图像的 URL 字符串的数组︰

var imageURLs: [String]

所以,你 NSData 应存储在一本字典 (或 NSCache ) 以该 URL 字符串为键︰

var imageData = [String: NSData]()

然后当你下载数据,您可以更新这本字典︰

self.imageData[imageURL] = dtA

然后,当你需要稍后检索此数据,您可以使用 imageURL,例如︰

let data = imageData[imageURLs[index]]

或者你可以将它定义为 [Int: NSData] 和使用了数字索引作为键。但这个想法是,你可以使用字典,然后你接收响应的顺序并不重要,但你仍然享受做并发请求的性能优势。


我认为会是这样︰

var imageData = [String: NSData]()

@IBAction func didClickOnStart(sender: AnyObject) {

    queue.cancelAllOperations()

    let completionOperation = NSBlockOperation() {
        print("all done")
    }

    for (index, imageURL) in imageURLs.enumerate() {
        let operation = DataOperation(session: session, urlString: imageURL) { data, response, error in
            guard let data = data where error == nil else { return }
            guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else { return }

            NSOperationQueue.mainQueue().addOperationWithBlock {
                self.imageData[imageURL] = data
            }
            print("JPEG download\(index)")
        }

        completionOperation.addDependency(operation)
        queue.addOperation(operation)
    }

    NSOperationQueue.mainQueue().addOperation(completionOperation)        
}

然后访问它像这样︰

if let data = imageData[imageURLs[index]], let image = UIImage(data: data) {
    // use `image` here
}

var imageData = [Int: NSData]()

@IBAction func didClickOnStart(sender: AnyObject) {

    queue.cancelAllOperations()

    let completionOperation = NSBlockOperation() {
        print("all done")
    }

    for (index, imageURL) in imageURLs.enumerate() {
        let operation = DataOperation(session: session, urlString: imageURL) { data, response, error in
            guard let data = data where error == nil else { return }
            guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else { return }

            NSOperationQueue.mainQueue().addOperationWithBlock {
                self.imageData[index] = data
            }
            print("JPEG download\(index)")
        }

        completionOperation.addDependency(operation)
        queue.addOperation(operation)
    }

    NSOperationQueue.mainQueue().addOperation(completionOperation)        
}

访问它像这样︰

if let data = imageData[index], let image = UIImage(data: data) {
    // use `image` here
}

注意, ImageNetworkOperation 只调用 DataOperationNSData ,然后将其转换为 UIImage 。如果你真的想要原始 NSData ,我会建议绕过 ImageNetworkOperation 和打电话只 DataOperation 直接,像如上所示。

官方微信
官方QQ群
31647020