循环中的 NSURLSession
NSURLSession in a loop
我希望 运行 这段代码可以从 URL 中获取多张图片,但是尽管循环 运行 遍历了数组中的每个对象,但唯一保存的对象是最后一个。有更好的方法吗?
编辑: 似乎所有图像都是从不同的 URL 保存的,但它们都以相同的文件名保存,循环中的最终文件名。这似乎是由于在 NSURLSession 和将图像写入文件时发生延迟引起的,文件名已经设置为循环的最后一个。
for object in objectArray {
url = NSURL(string:object.urlToLoad)
imageFile = paths.stringByAppendingPathComponent("\(object.filename).png")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
data.writeToFile(imageFile, atomically: true)
return
}
task.resume()
}
感谢您的帮助!
问题是它们都是 capturing/sharing 相同的 imageFile
变量,因为它是在 for
的范围之外声明的。所以首先你要遍历 n 次循环,在你进行时用下一个文件名覆盖 imageFile
变量并触发异步下载。然后,稍后,当每个 n 闭包在下载完成时实际执行时,它们都引用相同的文件名,该文件名与数组中的最后一个值匹配。
尝试在它前面加上一个 let
,从而在每次迭代中声明一个新的局部变量,每个闭包依次捕获该局部变量。你也应该对 url
做同样的事情,即使它碰巧不是问题。
一般来说,这是另一个很好的例子,说明您应该如何在每一次机会中使用 let
而不是 var
,并避免在外部范围内重复使用变量的做法,除非您特别指定想要将数据传送到外部范围。
这里有一些独立的代码演示了这一点,没有 URL 下载方面,只有 5 个并行的睡眠和打印 运行:
import Dispatch
let q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var shared: String = "shared=x"
for x: UInt32 in 1...5 {
shared = "shared=\(x)"
let unique = "unique=\(x)"
dispatch_async(q) {
sleep(x)
println("\(shared), \(unique)")
}
}
println("for loop completed, \(shared)")
dispatch_main()
我希望 运行 这段代码可以从 URL 中获取多张图片,但是尽管循环 运行 遍历了数组中的每个对象,但唯一保存的对象是最后一个。有更好的方法吗?
编辑: 似乎所有图像都是从不同的 URL 保存的,但它们都以相同的文件名保存,循环中的最终文件名。这似乎是由于在 NSURLSession 和将图像写入文件时发生延迟引起的,文件名已经设置为循环的最后一个。
for object in objectArray {
url = NSURL(string:object.urlToLoad)
imageFile = paths.stringByAppendingPathComponent("\(object.filename).png")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
data.writeToFile(imageFile, atomically: true)
return
}
task.resume()
}
感谢您的帮助!
问题是它们都是 capturing/sharing 相同的 imageFile
变量,因为它是在 for
的范围之外声明的。所以首先你要遍历 n 次循环,在你进行时用下一个文件名覆盖 imageFile
变量并触发异步下载。然后,稍后,当每个 n 闭包在下载完成时实际执行时,它们都引用相同的文件名,该文件名与数组中的最后一个值匹配。
尝试在它前面加上一个 let
,从而在每次迭代中声明一个新的局部变量,每个闭包依次捕获该局部变量。你也应该对 url
做同样的事情,即使它碰巧不是问题。
一般来说,这是另一个很好的例子,说明您应该如何在每一次机会中使用 let
而不是 var
,并避免在外部范围内重复使用变量的做法,除非您特别指定想要将数据传送到外部范围。
这里有一些独立的代码演示了这一点,没有 URL 下载方面,只有 5 个并行的睡眠和打印 运行:
import Dispatch
let q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var shared: String = "shared=x"
for x: UInt32 in 1...5 {
shared = "shared=\(x)"
let unique = "unique=\(x)"
dispatch_async(q) {
sleep(x)
println("\(shared), \(unique)")
}
}
println("for loop completed, \(shared)")
dispatch_main()