【问题标题】:Why I can change the get-only property?为什么我可以更改 get-only 属性?
【发布时间】:2020-06-18 05:10:34
【问题描述】:

谁能解释为什么我可以将值设置为 get-only 属性?

这是一个例子。此协议包含自定义类类型的 get-only 属性,以及符合它的类。

protocol ViewModel {
    var title: MyTitle { get }
}

class MyTitle {
    var title: String
    var otherProperty: Int
}

class MyViewModel: ViewModel {
    var title: MyTitle
    init() {
        self.title = MyTitle.init()
    }
    func didChangeTitle(title: String) {
        self.title.title = title
    }
}

我认为title属性应该是get-only,当用户编辑完UITextView时会触发MyViewModel中的函数。


class TableViewCell: UITableViewCell, UITextViewDelegate {
    var viewModel: MyViewModel?
    func bind(to viewModel: MyViewModel) {
        self.viewModel = viewModel
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        if text == "\n" {
            self.viewModel?.title.title = textView.text /* Why can the property supposed to be get-only be changed here */
            textView.resignFirstResponder()
            return false
        }
        return true
    }
}

但实际上我可以不用MyViewModel的功能直接更新值。

谁能解释一下?

【问题讨论】:

  • 你实际上并没有改变self.viewModel?.title。你正在改变self.viewModel?.title.title。更改类的属性不算作“更改类”。
  • 请注意,协议是要求而非限制。你可以设置 MyTitle 属性,只要它没有被声明为常量
  • @LeoDabus 所以如果我不想直接更改MyTitletitle,我应该将其声明为private 类型,对吧?
  • private 不允许从该类进行任何类型的访问。如果您想限制仅设置其值,请使用 private (set)
  • @LeoDabus 知道了!谢谢。

标签: swift get set protocols


【解决方案1】:

您实际上并没有通过遵守协议来声明get-only 属性。您可以使用计算属性,并通过

声明它
var title: String {
    return "Something"
}

此外,您正在更改类中的属性,而不是该类本身

编辑

或者按照 cmets 中的建议,您可以定义一个私有 setter private (set) var title: String

【讨论】:

  • 使用私有集 private (set) var title: String = "" 声明 title 会更容易避免从另一个类更改它
  • 是的,我忘记了,这实际上是如何声明 get-only 属性
猜你喜欢
  • 1970-01-01
  • 2018-08-30
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2012-02-10
相关资源
最近更新 更多