按顺序将图像附加到数组中
Append images in array in sequence
我想在下载后按顺序将图片添加到数组中。一张一张下载后,我将图像附加到数组中,但它们没有按顺序排列。谁能告诉我最好的方法是什么。
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
all done
尝试:
var previousOperation : NSOperation! = nil
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)
if (previousOperation != nil)
{
operation.addDependency(previousOperation)
}
previousOperation = operation
queue.addOperation(operation)
}
NSOperationQueue.mainQueue().addOperation(completionOperation)
这是一个非常快速和粗略的修复,当然还有更好的解决方案。问题的出现是因为操作队列中的操作是并发执行的,并且不能保证按它们开始的顺序完成。通过向循环中的先前操作添加依赖性,您可以确保它们按顺序执行
我不确定,但我认为,您无法控制下载顺序.. 意味着所有请求都通过管道传输到服务器(无论您创建 URL 对象的顺序如何)。您需要做的是,您必须维护包含 url 到实际数据映射的可变数组或字典,然后等待所有 url 完全下载。然后以已知顺序迭代。
您应该更改您的模型,这样图像的下载顺序就无关紧要了。例如,您有图像 URL 字符串数组:
var imageURLs: [String]
因此,您的 NSData
应该存储在由 URL 字符串键入的字典(或 NSCache
)中:
var imageData = [String: NSData]()
然后当你下载数据时,你可以更新这个词典:
self.imageData[imageURL] = dtA
然后,当您以后需要检索此数据时,可以使用图像URL,例如:
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
只是调用 DataOperation
来获取 NSData
,然后将其转换为 UIImage
。如果你真的想要原始的 NSData
,我建议绕过 ImageNetworkOperation
直接调用 ,如上所示。
我想在下载后按顺序将图片添加到数组中。一张一张下载后,我将图像附加到数组中,但它们没有按顺序排列。谁能告诉我最好的方法是什么。
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
all done
尝试:
var previousOperation : NSOperation! = nil
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)
if (previousOperation != nil)
{
operation.addDependency(previousOperation)
}
previousOperation = operation
queue.addOperation(operation)
}
NSOperationQueue.mainQueue().addOperation(completionOperation)
这是一个非常快速和粗略的修复,当然还有更好的解决方案。问题的出现是因为操作队列中的操作是并发执行的,并且不能保证按它们开始的顺序完成。通过向循环中的先前操作添加依赖性,您可以确保它们按顺序执行
我不确定,但我认为,您无法控制下载顺序.. 意味着所有请求都通过管道传输到服务器(无论您创建 URL 对象的顺序如何)。您需要做的是,您必须维护包含 url 到实际数据映射的可变数组或字典,然后等待所有 url 完全下载。然后以已知顺序迭代。
您应该更改您的模型,这样图像的下载顺序就无关紧要了。例如,您有图像 URL 字符串数组:
var imageURLs: [String]
因此,您的 NSData
应该存储在由 URL 字符串键入的字典(或 NSCache
)中:
var imageData = [String: NSData]()
然后当你下载数据时,你可以更新这个词典:
self.imageData[imageURL] = dtA
然后,当您以后需要检索此数据时,可以使用图像URL,例如:
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
只是调用 DataOperation
来获取 NSData
,然后将其转换为 UIImage
。如果你真的想要原始的 NSData
,我建议绕过 ImageNetworkOperation
直接调用