导致"self is immutable"错误的协议扩展默认方法



我正在尝试使用默认方法扩展类绑定协议(UITextInputTraits(:

extension UITextInputTraits where Self: UIView {
    func setTextInputTraits() {
        self.autocapitalizationType = .none // <- compiler error
    }
}

它给出了一个"Cannot assign to property: 'self' is immutable"错误。

如果我将约束从 UIView 更改为 UITextField,它会起作用,但这违背了使用协议的目的。

为什么是错误?如何实现此默认方法?

谢谢!


  • 无法标记 func mutating,因为'mutating' isn't valid on methods in classes or class-bound protocols
  • 尝试向自身发送消息,Objective-C 风格,但perform不适用于非对象值参数:

    func setTextInputTraits() {
        let sel = #selector(setter: self.autocapitalizationType)
        self.perform(sel, with: .none)
    }
    

如果我将约束从 UIView 更改为 UITextField,它会起作用,但这违背了使用协议的目的。为什么是错误?

因为 UIView 还没有autocapitalizationType属性。因此,编译器没有理由相信,如果它确实有一个,它将是可设置的。

如何实现此默认方法?

我想你可能会追求这样的事情:

protocol MyTextInputTraits : UITextInputTraits {
    var autocapitalizationType: UITextAutocapitalizationType {get set}
}
extension MyTextInputTraits {
    func setTextInputTraits() {
       self.autocapitalizationType = .none
    }
}
extension UITextView : MyTextInputTraits {}
extension UITextField : MyTextInputTraits {}
extension UISearchBar : MyTextInputTraits {}

最新更新