objective-c Swift 只读外部,读写内部属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25708439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift readonly external, readwrite internal property
提问by Jasper Blues
In Swift, what is the conventional way to define the common pattern where a property is to be externally readonly, but modifiable internally by the class (and subclasses) that own it.
在 Swift 中,定义公共模式的常规方法是什么,其中属性在外部是只读的,但可以由拥有它的类(和子类)在内部修改。
In Objective-C, there are the following options:
在 Objective-C 中,有以下选项:
- Declare the property as readonly in the interface and use a class extension to access the property internally. This is message-based access, hence it works nicely with KVO, atomicity, etc.
- Declare the property as readonly in the interface, but access the backing ivar internally. As the default access for an ivar is protected, this works nicely in a class hierarchy, where subclasses will also be able to modify the value, but the field is otherwise readonly.
- 在接口中将该属性声明为只读,并使用类扩展在内部访问该属性。这是基于消息的访问,因此它可以很好地与 KVO、原子性等配合使用。
- 在接口中将属性声明为只读,但在内部访问支持的 ivar。由于 ivar 的默认访问权限受到保护,因此这在类层次结构中非常有效,其中子类也可以修改该值,但该字段是只读的。
In Java the convention is:
在 Java 中,约定是:
- Declare a protected field, and implement a public, read-only getter (method).
- 声明一个受保护的字段,并实现一个公共的、只读的 getter(方法)。
What is the idiom for Swift?
Swift 的成语是什么?
回答by Antonio
Given a class property, you can specify a different access level by prefixing the property declaration with the access modifier followed by getor setbetween parenthesis. For example, a class property with a public getter and a private setter will be declared as:
给定一个类属性,您可以通过在属性声明前加上访问修饰符后跟括号get或set括号之间来指定不同的访问级别。例如,具有公共 getter 和私有 setter 的类属性将声明为:
private(set) public var readonlyProperty: Int
Suggested reading: Getters and Setters
推荐阅读:Getter 和 Setter
Martin's considerations about accessibility level are still valid - i.e. there's no protectedmodifier, internalrestricts access to the module only, privateto the current file only, and publicwith no restrictions.
Martin 关于可访问性级别的考虑仍然有效 - 即没有protected修饰符,internal仅限制对模块的访问,仅对private当前文件的访问,并且public没有任何限制。
Swift 3 notes
斯威夫特 3 笔记
2 new access modifiers, fileprivateand openhave been added to the language, while privateand publichave been slightly modified:
2 个新的访问修饰符,fileprivate并open已添加到语言中,而private和public已稍作修改:
openapplies to class and class members only: it's used to allow a class to be subclassed or a member to be overridden outside of the module where they are defined.publicinstead makes the class or the member publicly accessible, but not inheritable or overridableprivatenow makes a member visible and accessible from the enclosing declaration only, whereasfileprivateto the entire file where it is contained
open仅适用于类和类成员:它用于允许类被子类化或成员在定义它们的模块之外被覆盖。public而是使类或成员可公开访问,但不可继承或可覆盖private现在使成员仅从封闭声明中可见和可访问,而fileprivate对包含它的整个文件
More details here.
更多细节在这里。
回答by Santosh
As per @Antonio, we can use a single property to access as the readOnlyproperty value publicly and readWriteprivately. Below is my illustration:
根据@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)")
And here is the output:
这是输出:
Initial valule: 10
After increment method call: 11
After decrement method call: 10

