swift - Unexpected Cannot assign to property 'self' is immutable compile time error IN CLASS

标签 swift class struct immutability swift-protocols

现在这是 Swift 编译器的一种奇怪行为。我得到一个 Cannot assign to property 'self' is immutable类中的编译时错误。这是最小的游乐场代码:

import UIKit

open class TextInputTraitsWrapper: NSObject {
    private var wrapped: UITextInputTraits
    
    public init(wrapped: UITextDocumentProxy) {
        self.wrapped = wrapped
        super.init()
    }
    
    open var keyboardAppearance: UIKeyboardAppearance {
        get {
            return wrapped.keyboardAppearance ?? UIKeyboardAppearance.default
        }
        set {
            wrapped.keyboardAppearance = newValue // ERROR ON THIS LINE
        }
    }
}
这是我得到的错误(这是完整的程序):
enter image description here
作为附注协议(protocol) UITextInputTraits定义 keyboardAppearance像这样:optional var keyboardType: UIKeyboardType { get set } .
为什么我在类里面会出现这种错误?

最佳答案

这是一个错误,但不是您可能认为的错误(并且错误消息根本没有帮助)。这是一个 known bug由于 keyboardAppearance UITextInputTraits 协议(protocol)的属性是 optional属性(意味着它可能不会被实现)。这是一个 Objective C 特性,而不是 Swift 特性,并且错误是这些属性在 Swift 中不能直接设置,即使它们被标记为 {get set} .
为了看到这一点,让我们为自己模拟相同的模式:

@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
        }
    }
}
我们得到同样的错误。但是如果删除关键字optional ,错误消失。这证明 optional是导致问题的原因。但是你不能删除optional在您的情况下,因为该协议(protocol)不属于您。
解决方法与原始错误相同 - 使用关键路径:
let kp = \C.wrapped.keyboardAppearance
self[keyPath:kp] = newValue

关于swift - Unexpected Cannot assign to property 'self' is immutable compile time error IN CLASS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66082736/

相关文章:

java - 内部类属性

c++ - istream 和 ostream 问题 - C++

ios - 从照片中获取后,视频及其缩略图未按顺序保存

ios - 从 UIImage 创建 MSSticker

css - 将 CSS 类用于个别效果 - 意见?

c++ - 为什么 C 和 C++ 中 ` struct T{ double x};` 的输出不同?

c++ - 将值存储在结构 vector 的映射中

C++ union/结构位域实现和可移植性

swift - 布局约束使 NSView 的行为类似于 NSImageView 中的 NSImage

swift - 除非滚动,否则 UICollectionViewCells 不会加载