Suppose you have some structs like:
struct Tattoo {
var imageTorso:UIImage?
var imageTorsoURL:URL?
var imageArms:UIImage?
var imageArmsURL:URL?
}
struct Player {
var name:String = ""
var tattoos:[Tattoo] = []
}
struct Team {
var name:String = ""
var players:[Player] = []
}
Now imagine that you have a method that was passed in a Team value with some players. You have to iterate thru the players and their tattoos, then download the images and add them into the images variables on the tattoos.
If you use a for in
loop, then it won't work because each part of the loop gets a copy of the members of the array it's iterating over. I.e.:
for player in team.players {
for tattoo in player.tattoos {
if let url = tattoo.imageTorsoURL {
MyNetFramework.requestImage(from: url, completion: { image in
tattoo.imageTorso = image
}
}
}
}
After doing all the iterations and completion blocks, still, the original team
variable is identical to what it was prior to doing any of this. Because each tattoo that the inner loop got was a copy of what is in the player's tattoos array.
Now I know you can use &
to pass structs by reference in Swift but it's highly discouraged. As well I know you can use inout
so they don't get copied when they come into functions, which is also discouraged.
I also know these could be made classes to avoid this behavior.
But supposing I don't have a choice in the matter -- they are structs -- it seems the only way to do this is something like:
for p in 0...team.players.count-1 {
for t in 0...team.players[p].tattoos.count-1 {
if let url = team.players[p].tattoos[t].imageTorsoURL {
MyNetFramework.requestImage(from: url, completion: { image in
team.players[p].tattoos[t].imageTorso = image
}
}
}
}
This feels ugly and awkward, but I don't know how else to get around this thing where for in
loops give you a copy of the thing you're iterating through.
Can anyone enlighten me, or is this just how it is in Swift?