arrays – 在特定索引处交换数组值?

我正在为一些字典数组创建异步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
3

Actual:
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])

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...