Swift readonly 외부, readwrite 내부 속성


103

Swift에서 속성이 외부 적으로는 읽기 전용이지만 속성을 소유 한 클래스 (및 하위 클래스)가 내부적으로 수정할 수있는 공통 패턴을 정의하는 일반적인 방법은 무엇입니까?

Objective-C에는 다음과 같은 옵션이 있습니다.

  • 인터페이스에서 속성을 읽기 전용으로 선언하고 클래스 확장을 사용하여 속성에 내부적으로 액세스합니다. 이것은 메시지 기반 액세스이므로 KVO, 원 자성 등에서 잘 작동합니다.
  • 인터페이스에서 속성을 읽기 전용으로 선언하지만 내부적으로 백업 ivar에 액세스합니다. ivar에 대한 기본 액세스가 보호되므로 하위 클래스도 값을 수정할 수 있지만 필드는 읽기 전용 인 클래스 계층 구조에서 잘 작동합니다.

Java에서 규칙은 다음과 같습니다.

  • 보호 된 필드를 선언하고 공용 읽기 전용 getter (메소드)를 구현합니다.

Swift의 관용구는 무엇입니까?

답변:


219

클래스 속성이 주어지면 속성 선언 앞에 액세스 수정 자 뒤에 괄호 가 get오거나 set괄호 사이에 추가 되어 다른 액세스 수준을 지정할 수 있습니다 . 예를 들어, public getter와 private setter가있는 클래스 속성은 다음과 같이 선언됩니다.

private(set) public var readonlyProperty: Int

추천 자료 : 게터와 세터

접근성 수준에 대한 Martin의 고려 사항은 여전히 ​​유효합니다. 즉 protected, 수정자가 없고 internal모듈에 대한 액세스 만 제한 private하고 현재 파일에만 제한없이 액세스를 public제한합니다.

Swift 3 노트

이 새로운 액세스 수식 자, fileprivate하고 open있는 동안, 언어에 추가되었습니다 privatepublic약간 수정되었습니다 :

  • open클래스 및 클래스 멤버에만 적용됩니다. 클래스가 하위 클래스로 지정되거나 멤버가 정의 된 모듈 외부에서 재정의되도록 허용하는 데 사용됩니다. public대신 클래스 또는 멤버를 공개적으로 액세스 할 수 있지만 상속하거나 재정의 할 수는 없습니다.

  • private이제 fileprivate포함 된 전체 파일에서 멤버를 표시하고 둘러싸는 선언에서만 액세스 할 수 있습니다.

자세한 내용은 여기를 참조 하세요 .


좋은! (I 누락 된 추가 할 자유를 가지고있다 var가 컴파일 할 수있는 키워드를.)
마틴 R

오 고마워요 :) 저는 보통 놀이터에서 복사하여 붙여 넣지 만 이번에는 아마 잘못했을 것입니다.
Antonio

10
1 월 2015 년 참고이 구문은 확실히 바로 외부 클래스가없는 경우 public-이 없어야 internal또는 전혀 아무것도 (기본값 클래스가 무엇이든에 - publicinternal) - 예private(set) var readonlyProperty: Int
Grimxn

1
글쎄요 구문은 코드 직전 공개 getter와 private setter 로 클래스 속성을 작성했다는 점을 고려하면 정확합니다 . 그러나 예, 속성에 대한 액세스 수정자는 클래스 / 구조체 액세스 수정 자와 "호환"되어야합니다.
Antonio

마지막 단락과 관련하여 답변이 작성된 이후로 변경되었지만 private이제는 현재 선언 (파일이 아님) fileprivate으로 제한되고 현재 파일로 제한 할 수 있습니다. 또한 public몇 가지 제한 사항이 있으며 제한 사항 open이 없습니다. 자세한 내용은 여기 .
나이젤 B. 펙

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.