我正在为一些字典数组创建异步NSURLConnections,每个字典都有自己的图像URL:
var posts = [ ["url": "url0","calledindex": 0],["url": "url1","calledindex": 1],["url": "url2","calledindex": 2],["url": "url3","calledindex": 3] ]
鉴于连接的异步性质(这是我想要的,最快的图像首先加载),图像可能以不同的顺序加载,例如:
url0 url2 url3 url1
但是,如果图像无序加载,则需要根据加载图像的时间重新组织原始的帖子数组.因此,鉴于以上示例,帖子现在应该如下所示:
var posts = [ ["url": "url0","calledindex": 3],"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]) } }
然后,我尝试了类似的东西,没有交换功能:
// 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值,导致它交换回原来的位置.
这个假设可能是完全错误的,我意识到我很难描述这种情况,但我会尽量提供尽可能多的澄清.
我做了一个测试用例,你可以download the source code here.它的代码是:
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 }
输出是:
Loaded:
1
0
2
3Actual:
0
1
2
3
但是,预期的“实际”输出应为:
1 0 2 3
值得注意的是,使用元组代码会导致稍微不稳定的结果,但没有任何与实际顺序相匹配的结果.您可以通过取消注释该行来了解我的意思.
你可以通过元组分配:
var xs = [1,2,3] (xs[1],xs[2]) = (xs[2],xs[1])
但是你实际上有什么问题与交换?以下应该可以正常工作:
swap(&xs[1],&xs[2])