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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:25:25  来源:igfitidea点击:

Swift readonly external, readwrite internal property

objective-cpropertiesswift

提问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:

给定一个类属性,您可以通过在属性声明前加上访问修饰符后跟括号getset括号之间来指定不同的访问级别。例如,具有公共 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 个新的访问修饰符,fileprivateopen已添加到语言中,而privatepublic已稍作修改:

  • 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 overridable

  • privatenow makes a member visible and accessible from the enclosing declaration only, whereas fileprivateto 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