Swift只读外部,读写内部属性


103

在Swift中,定义公共模式的常规方式是什么,在该模式中,属性是外部只读的,但可以由拥有该属性的类(和子类)在内部进行修改。

在Objective-C中,有以下选项:

  • 在接口中将该属性声明为只读,并使用类扩展名在内部访问该属性。这是基于消息的访问,因此可以很好地与KVO,原子性等配合使用。
  • 在接口中将该属性声明为只读,但在内部访问后备ivar。由于对ivar的默认访问受到保护,因此在类层次结构中效果很好,在该类层次结构中,子类也可以修改值,但该字段为只读。

在Java中,约定为:

  • 声明一个受保护的字段,并实现一个公共的只读getter(方法)。

Swift的成语是什么?

Answers:


217

给定一个类属性,您可以通过在属性声明的前面加上access修饰符(get或)来指定其他访问级别set在括号之间括号之间。例如,具有公共获取器和私有设置器的类属性将声明为:

private(set) public var readonlyProperty: Int

建议阅读:Getters和Setters

Martin关于可访问性级别的考虑仍然有效-即没有protected修饰符,internal仅限制对模块的访问,private当前文件的访问,并且public没有任何限制。

斯威夫特3笔记

2个新的访问修饰符,fileprivate并且open已添加到语言中,而privatepublic则稍作修改:

  • open仅适用于类和类成员:用于允许对类进行子类化或在定义它们的模块之外重写成员。public而是使类或成员可公开访问,但不能继承或覆盖

  • private现在使成员仅从封闭的声明中可见并可以访问,而fileprivate对于包含该成员的整个文件

更多细节在这里


真好!(我可以随意添加缺少的var关键字来进行编译。)
Martin R

哦,非常感谢:)我通常从操场复制并粘贴,但是这次我可能做错了。
安东尼奥

10
请注意,自2015年1月起,如果外部类不是public,则该语法不太正确-它应该是internal或根本不存在(默认为类是- publicinternal)-即private(set) var readonlyProperty: Int
Grimxn15年

1
好吧,语法是正确的,考虑到我在代码之前写了一个带有公共获取器和私有设置器的类属性 -这只是一个例子。但是可以,属性的访问修饰符必须与类/结构访问修饰符“兼容”。
Antonio

关于最后一段,我想自从编写答案以来,这已经发生了变化,但是private现在限制为当前声明(不是文件),fileprivate并且可以用于限制为当前文件。也public有一些限制,open没有限制是必需的。详细信息在这里
Nigel B. Peck

2

根据@Antonio,我们可以使用单个属性readOnly公开和readWrite私有访问属性值。下面是我的插图:

class MyClass {

    private(set) public var publicReadOnly: Int = 10

    //as below, we can modify the value within same class which is private access
    func increment() {
        publicReadOnly += 1
    }

    func decrement() {
        publicReadOnly -= 1
    }
}

let object = MyClass()
print("Initial  valule: \(object.publicReadOnly)")

//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1

object.increment()
print("After increment method call: \(object.publicReadOnly)")

object.decrement()
print("After decrement method call: \(object.publicReadOnly)")

这是输出:

  Initial  valule: 10
  After increment method call: 11
  After decrement method call: 10
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.