我正在基于一个包含多个字典的数组创建异步NSURLConnections
来加载图片,每个字典都有自己的图片URL:
var posts = [
["url": "url0", "calledIndex": 0],
["url": "url1", "calledIndex": 1],
["url": "url2", "calledIndex": 2],
["url": "url3", "calledIndex": 3]
]
考虑到连接的异步性(这正是我所需要的,使图像尽快加载),图像可能以不同的顺序加载,例如:
url0
url2
url3
url1
如果图片的加载顺序不正确,原始的
posts
数组需要根据图片加载的时间重新组织。因此,给定上面的示例,posts
现在应该如下所示:var posts = [
["url": "url0", "calledIndex": 0],
["url": "url2", "calledIndex": 2],
["url": "url3", "calledIndex": 3],
["url": "url1", "calledIndex": 1]
]
在Swift中,有没有一种方法可以交换数组中特定索引处的值与相同数组中不同索引处的值?我首先尝试使用swap
函数:
// Index the images load
var loadedIndex = 0
func connectionDidFinishLoading(connection: NSURLConnection) {
// Index of the called image in posts
let calledIndex = posts["calledIndex"] as! Int
// Index that the image actually loaded
let loadedIndex = loadedIndex
// If the indicies are the same, the image is already in the correct position
if loadedIndex != calledIndex {
// If they're not the same, swap them
swap(&posts[calledIndex], &posts[loadedIndex])
}
}
我随后尝试了一些类似的操作,但没有使用swap
函数:
// The post that was actually loaded
let loadedPost = posts[calledIndex]
// The post at the correct index
let postAtCorrectIndex = posts[loadedIndex]
posts[calledIndex] = postAtCorrectIndex
posts[loadedIndex] = loadedPost
在这两种情况下,数组值并没有正确交换。我意识到这是一个逻辑错误,但我无法看出错误实际上在哪里。
据我所知,它第一次交换时是正确的,但是新字典有一个不正确的calledIndex值,导致它回到原来的位置。
这个假设可能是完全错误的,我意识到我很难描述这种情况,但我会尽可能提供更多的澄清。
我做了一个测试用例,你可以在这里下载源代码。它的代码如下:
var allPosts:Array<Dictionary<String, AnyObject>> = [
["imageURL": "http://i.imgur.com/aLsnGqn.jpg", "postTitle":"0"],
["imageURL": "http://i.imgur.com/vgTXEYY.png", "postTitle":"1"],
["imageURL": "http://i.imgur.com/OXzDEA6.jpg", "postTitle":"2"],
["imageURL": "http://i.imgur.com/ilOKOx5.jpg", "postTitle":"3"],
]
var lastIndex = 0
var threshold = 4
var activeConnections = Dictionary<NSURLConnection, Dictionary<String, AnyObject?>>()
func loadBatchInForwardDirection(){
func createConnection(i: Int){
allPosts[i]["calledIndex"] = i
var post = allPosts[i]
let imageURL = NSURL(string: post["imageURL"] as! String)
if imageURL != nil {
let request = NSMutableURLRequest(URL: imageURL!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
let connection = NSURLConnection(request: request, delegate: self, startImmediately: true)
if connection != nil {
activeConnections[connection!] = post
}
}
}
let startingIndex = lastIndex;
for (var i = startingIndex; i < startingIndex + threshold; i++){
createConnection(i)
lastIndex++
}
}
func connection(connection: NSURLConnection, didReceiveData data: NSData) {
if activeConnections[connection] != nil {
let dataDict = activeConnections[connection]!["data"]
if dataDict == nil {
activeConnections[connection]!["data"] = NSMutableData(data: data)
} else {
(activeConnections[connection]!["data"] as! NSMutableData).appendData(data)
}
}
}
var loadedIndex = 0
func connectionDidFinishLoading(connection: NSURLConnection) {
let loadedPost = activeConnections[connection]!
activeConnections.removeValueForKey(connection)
let data = loadedPost["data"] as? NSData
let calledIndex = loadedPost["calledIndex"] as! Int
println(calledIndex)
swap(&allPosts[calledIndex], &allPosts[loadedIndex])
//(allPosts[calledIndex], allPosts[loadedIndex]) = (allPosts[loadedIndex], allPosts[calledIndex])
loadedIndex++
done(loadedIndex)
}
func done(index: Int){
if index == 4 {
println()
println("Actual: ")
println(allPosts[0]["postTitle"] as! String)
println(allPosts[1]["postTitle"] as! String)
println(allPosts[2]["postTitle"] as! String)
println(allPosts[3]["postTitle"] as! String)
}
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
loadBatchInForwardDirection()
println("Loaded: ")
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
输出结果为:
已加载: 1 0 2 3
实际结果: 0 1 2 3
然而,"实际结果"应该是:
值得注意的是,使用元组代码会导致略微有些不正常的结果,但没有匹配实际排序的内容。您可以通过取消注释该行来查看我的意思。1 0 2 3
swap
或 Rob 的元组代码更好吗? - Charlie