Reputation: 1851
I'm trying to update a property on a service that is defined as let subscriber: SubscriberContextProviding
in the WatchlistViewModel
by simply setting it directly like so:
subscriber.watchlist = watchlist
relevant subscriber definition:
final class Subscriber: SubscriberContextProviding {
var watchlist = [String]()
}
however I get an error saying: Cannot assign to property: 'subscriber' is a 'let' constant
. The subscriber service is declared as a let
and is initialised in the client init
.
here is the relevant protocol part & init
.
protocol SubscriberContextProviding {
var watchlist: [String] { get set }
}
class WatchlistViewModel: NSObject {
let subscriber: SubscriberContextProviding
init(subscriber: SubscriberContextProviding){
self.subscriber = subscriber
super.init()
}
}
however If I change the protocol from the one above to
protocol SubscriberContextProviding {
func set(watchlist: [String])
}
and I simply define the function in the subscriber
as
func set(watchlist: [String]){
self.watchlist = watchlist
}
and instead of setting the property directly now using the function like so
subscriber.set(watchlist: watchlist)
works no problem. Why the first approach doesn't work while the latter one does as the result is the same of both approaches?
Upvotes: 2
Views: 2083
Reputation: 63167
The "issue" (though it's not an issue, really) is that you haven't restricted SubscriberContextProviding
to being a class-bound protocol (with : AnyObject
).
let subscriber: SubscriberContextProviding
is declaring that your subscriber
variable with contain an existential of any object whose type conforms to SubscriberContextProviding
. Since that protocol isn't class-bound, it's possible that the concrete value you're dealing with is a value type (tuple, struct or enum), for which mutations are only allowed on mutable var
variables. This existential is itself a value type, and abides the same rules of only allowing mutations on var
variables.
Thus, you must either:
Declare SubscriberContextProviding
as class-bound:
protocol SubscriberContextProviding: AnyObject { ... }
or
Keep your protocol as-is, but make your subscriber
variable mutable, to account for the possibility that it contains a value type.
Upvotes: 7
Reputation: 4171
Add this to your protocol:
protocol SubscriberContextProviding: AnyObject{
var watchlist: [String] { get set }
}
Upvotes: 1