I'm converting a project from Objective-C to Swift, and am running into a lot of bugs based on the change from an NSDictionary being a class that copies by reference to a Dictionary being a struct that copies by value. Here's a simplified example:
var recentMessages = [String: [String]]()
func logMessage(_ message: String, forChannel channel: String) {
let channelMessages = self.recentMessages[channel]
channelMessages.append(message)
}
In Objective-C, that updated the recentMessages
property. In Swift, that only updates the channelMessages
variable in the function scope, and I have to copy the change back to the property:
var recentMessages = [String: [String]]()
func logMessage(_ message: String, forChannel channel: String) {
let channelMessages = self.recentMessages[channel]
channelMessages.append(message)
self.recentMessages[channel] = channelMessages
}
This workaround isn't difficult, and this answer called it the best approach four years ago. But it is adding a lot of clutter and I'm afraid of forgetting to apply it every time. Is there a way to more directly replicate the previous behavior?
I could avoid creating the local variable and update the property directly, but that seems like a big limitation and in more complex cases that will make the code hard to read:
var recentMessages = [String: [String]]()
func logMessage(_ message: String, forChannel channel: String) {
self.recentMessages[channel].append(message)
}
In cases where the dictionary will be used repeatedly and with predictable keys, I think creating a custom class with properties that support all the keys would solve it. But I have places where a dictionary could include arbitrary keys that aren't predefined, or where a dictionary is only used briefly and creating a class for it would be overkill.
Is there another approach I'm missing that would restore that "copy by reference" behavior my current codebase depends on?
Aucun commentaire:
Enregistrer un commentaire