Cannot assign to property in protocol constrained to class - Swift compiler error
In the first case it should be considered an "unimplemented feature" (that the compiler cannot infer the behavior of a class in this context). So to fix it you have to make the value
a var
:
func afterViewInstantiated <V : ViewForViewModel where V: UIViewController, V.ViewModelType: AnyObject>(var view : V, viewModel: V.ViewModelType) -> V
In the second case you should provide more information about the error (message) and the types. Where does V
come from?
Cannot assign to property: 'point' is a 'let' constant
PointType
as a protocol, as written, could apply to either a value type (such as a struct) or a reference type (such as a class). If it were a value type and passed to your function without inout
, it would be immutable.
If your PointType
is always going to be a reference type (and thus always mutable from inside a function where it's pointed to by reference), you can fix your error by saying that it has to be AnyObject
:
protocol PointType : AnyObject {
Unexpected Cannot assign to property 'self' is immutable compile time error IN CLASS
It's a bug, but not the bug you might think (and the error message is no help at all). It's a known bug caused by the fact that the keyboardAppearance
property of the UITextInputTraits protocol is an optional
property (meaning that it might not be implemented). This is an Objective C feature, not a Swift feature, and the bug is that such properties are not directly settable in Swift, even when they are marked {get set}
.
To see this, let's emulate the same schema for ourselves:
@objc public protocol P {
@objc optional var keyboardAppearance : NSString {get set}
}
open class C : NSObject {
private var wrapped: P
public init(wrapped: P) {
self.wrapped = wrapped
super.init()
}
open var keyboardAppearance : NSString {
get {
wrapped.keyboardAppearance ?? "" as NSString
}
set {
wrapped.keyboardAppearance = newValue
}
}
}
We get the same error. But if you delete the keyword optional
, the error goes away. This proves that the optional
is what causes the issue. But you cannot delete optional
in your situation, because that protocol doesn't belong to you.
The workaround is the same as for the original bug — use a key path:
let kp = \C.wrapped.keyboardAppearance
self[keyPath:kp] = newValue
Cannot assign to a property: 'class' is a 'let' constant
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.
Swift error saying it cannot assign to property due to it being a 'let' constant
You are accessing the local variable captureDevice
, not the struct's captureDevice
variable.
Just replace the line causing the error to the following:
self.captureDevice?.exposureMode = .continuousAutoExposure
Note the self.
before captureDevice
.
You might think of changing the conditional binding to using var
instead of let
, but that won't actually work. This is because you are just mutating a local copy. It will fix the compile error but the logic won't work.
Cannot assign to property: 'self' is immutable swift error
Make the protocol become reference type
protocol Positions: AnyObject {
Cannot assign to property: 'outputs' is a get-only property
The issue is that ViewModelOutputsType
can either be a value or reference type. If it is a value type, then mutating any of its properties mutates the instance itself. You can resolve the issue by making the protocol class constrained and hence guaranteeing it to be a reference type.
protocol ViewModelOutputsType: class {
var didReceiveServiceError: ((Error) -> Void) { get set }
var reloadData: (() -> Void) { get set }
}
Related Topics
Having App Restart Itself When It Detects Change to Privacy Settings
What Is Difference Between Urlwithstring and Fileurlwithpath of Nsurl
How to Identify iOS Device Uniquely
Nsgenericexception Reason Collection <Nsconcretemaptable: Xxx>
Fetching Selected Attribute in Entities
How to Integrate Crashlytics into an iOS Framework Target
iOS Name of This Way of Building and Returning an Object in Objective-C
What's the Point of Nsassert, Actually
Watchkit Extension Bundle Identifiers
How to Position Views on Top of Each Other
Main.Async VS Main.Sync() VS Global().Async in Swift3 Gcd
Disable Wkwebview for Opening Links to Redirect to Apps Installed on My Iphone
Deferredlocationupdatesavailable Returns No in iOS 10
How to Share Nsdata or Phasset Video Using Facebook iOS Sdk 4.0 Fbsdksharedialog
Spritekit: Why Does It Wait One Round for the Score to Update? (Swift)