如何在嵌套循环中访问变量?

How to access the variable in a nested loop?

我试图在嵌套循环中访问 "x" 的值,但每次我尝试此操作时,在内循环中 "x" 的值都会发生变化。

var downloads_array = [[URL]]()//edited
func downloadImages(){

        var count = images.count
        let storage = Storage.storage().reference()

        for x in 0...count-1{
            var anime = [String]()
            anime.append(images[x])
            anime.append(images[x] + "1")
            print("outside the second loop x is : \(x)")

            for i in anime{
                let storageRef = storage.child("images/\(i).jpg")
                storageRef.downloadURL { (url, error) in
                    if let error = error{
                        print(error.localizedDescription)
                    }
                    else{
                        print(x)
                        self.downloads_array[x].append(url!)//edited
                    }
                }
            }
        }

    }

输出是:

outside the second loop x is : 0
outside the second loop x is : 1
outside the second loop x is : 2
outside the second loop x is : 3
outside the second loop x is : 4
outside the second loop x is : 5
0
3
0
1
1
4
2
5
3
4
2
5

我是 swift 开发的新手,请指导我解决这个问题。

您的 storageRef.downloadURL 是一个 async 调用,这意味着执行完成块需要时间。 for 循环将被执行,并且 count * 2 个调用将被命中。根据收到每个响应的速度,调用适当的完成会导致您获得的顺序。

func downloadImages(){
    var count = images.count
    let storage = Storage.storage().reference()

    for x in 0...count-1{
        var anime = [String]()
        anime.append(images[x])
        anime.append(images[x] + "1")
        print("outside the second loop x is : \(x)")

        print(x) // printing it here will give you the order as is
        for i in anime {
            let storageRef = storage.child("images/\(i).jpg")
            storageRef.downloadURL { (url, error) in
                if let error = error{
                    print(error.localizedDescription)
                }
                else{
                    print(x)
                }
            }
        }
    }
}

因为您无法控制完成块的执行顺序。字典将是解决您问题的一种方法。将 index 存储为 key 并将 url array 存储为 。或者你可以有一个 struct 存储相应索引的 urls 和 sort 它。

不确定你到底需要什么,但我认为你正在尝试实现这样的东西:-

func downloadImages(){
    var count = images.count
    let storage = Storage.storage().reference()
    var data : [String:Int] = []
    for x in 0...count-1{
        var anime = [String]()
        anime.append(images[x])
        anime.append(images[x] + "1")
        print("outside the second loop x is : \(x)")

        for i in anime {
            let storageRef = storage.child("images/\(i).jpg")
            data["YourUrl"] = x // Replace YourUrl with your url string
            storageRef.downloadURL { (url, error) in
                if let error = error{
                    print(error.localizedDescription)
                }
                else{
                    if let value = data[url.absoluteString]{
                        print(value)
                    }

                }
            }
        }
    }
}

storageRef.downloadURLasync 因此代码将继续执行并且 x 值将更改。这里的解决方案是通过中间变量或块捕获来捕获当前 x 值

块捕获

var downloads_array = [[URL]]()//edited
func downloadImages(){

    var count = images.count
    let storage = Storage.storage().reference()

    for x in 0...count-1{
        var anime = [String]()
        anime.append(images[x])
        anime.append(images[x] + "1")
        print("outside the second loop x is : \(x)")

        for i in anime{
            let storageRef = storage.child("images/\(i).jpg")
            storageRef.downloadURL { [x] (url, error) in // block capture
                if let error = error{
                    print(error.localizedDescription)
                }
                else{
                    print(x)
                    self.downloads_array[x].append(url!)//edited
                }
            }
        }
    }

}

-

中间变量

var downloads_array = [[URL]]()//edited
func downloadImages(){

    var count = images.count
    let storage = Storage.storage().reference()

    for x in 0...count-1{
        var anime = [String]()
        anime.append(images[x])
        anime.append(images[x] + "1")
        print("outside the second loop x is : \(x)")

        for i in anime{
            let storageRef = storage.child("images/\(i).jpg")
            let currentX = x // intermediary variable
            storageRef.downloadURL { (url, error) in
                if let error = error{
                    print(error.localizedDescription)
                }
                else{
                    print(currentX)
                    self.downloads_array[currentX].append(url!)//edited
                }
            }
        }
    }

}

由于 Firebase 存储是一个异步调用(网络调用),我们无法保留该值,因为顺序将是非连续的。所以我用 String 和 URL 创建了一个字典来存储图像 URL 的相应下载