티스토리 뷰

iOS/Swift

[Swift] 접근제어 (Access Control)

HarryJeonn 2023. 1. 26. 02:52

접근제어

특정 코드의 접근을 다른 소스파일이나 모듈에서 제한하는 것이다.

이렇게 접근제어를 함으로써 특정 코드의 세부적인 구현을 감추고 딱 필요한만큼 공개해 다른 곳에서 사용할 수 있도록 한다.

클래스, 구조체, 열거형 등 개별 타입에도 적용할 수 있고 그 타입에 속한 프로퍼티, 메소드, 초기자, 서브스크립트에도 적용할 수 있다.

프로토콜은 그래서 전역상수, 변수, 함수같이 특정 문맥에 종속된다.

Swift에서는 기본 접근레벨을 제공해 접근레벨의 처리를 쉽게할 수 있도록 돕는다. 그래서 사실 단일 타겟의 앱에서는 특별히 접근레벨을 전혀 명시하지 않아도 된다.

모듈과 소스파일

Swift의 접근제어는 모듈과 소스파일에 기반을 두고있다. 모듈을 코드를 배포하는 단일 단위로 하나의 프레임워크나 앱이 이 단위로 배포되고 다른 모듈에서 Swift의 import 키워드를 사용해 import 될 수 있다.

Xcode의 각 빌드 타겟은 Swift에서 분리된 단일 모듈로 취급된다.

소스파일은 모듈안에 있는 소스파일을 의미한다. 각 소스파일에 여러 특정 타입을 선언해 사용할 수 있다.

접근레벨

  • Open
    • 선언한 모듈이 아닌 다른 모듈에서 사용가능하다.
    • 다른 모듈에서 오버라이드와 서브클래싱이 가능하다.
  • Public
    • 선언한 모듈이 아닌 다른 모듈에서 사용가능하다.
    • 다른 모듈에서 오버라이드와 서브클래싱이 불가능하다.
  • Internal
    • 기본 접근레벨로 아무 접근레벨을 선언하지 않으면 Internal로 간주된다. Internal 레벨로 선언되면 해당 모듈 전체에서 사용 가능하다.
  • File-private
    • 특정 엔티티를 선언한 파일 안에서만 사용 가능하다.
  • Private
    • 특정 엔티티가 선언된 괄호{} 안에서만 사용 가능하다.

접근레벨 가이드 원칙

Swift에서 접근 레벨은 더 낮은 레벨을 갖고 있는 다른 엔티티를 특정 엔티티에 선언해 사용할 수 없다는 일반 가이드 원칙을 따른다.

몇 가지 예시를 보자.

private class SomeClass {
	public func method() { }
}

private 접근 레벨안에서 public 접근 레벨을 사용할 수 없다.

클래스(상위요소)가 private이기 때문에 method()도 private로 취급된다.

public func method(_ : SomeClass) { }

위에서 method()함수는 public이기 때문에 private 레벨인 SomeClass를 받아올 수 없다.

앱, 프레임워크를 위한 접근레벨

단일 타겟 앱에서는 특별히 접근레벨을 명시할 필요가 없지만 필요에 따라 file-private, private 등을 사용해 앱 내에서 구현 세부사항을 숨길 수 있다.

프레임워크를 개발한다면 public 혹은 open으로 지정해서 다른 모듈에서 볼 수 있고 접근 가능하도록 만들어야 한다.

유닛 테스트를 위한 접근레벨

위에서 open이나 public으로 지정된 엔티티만 다른 모듈에서 접근이 가능하다고 했다.

하지만 유닛 테스트를 하는 경우 모듈을 import할 때 import앞에 @testable 이라는 애트리뷰트를 붙여주면 해당 모듈을 테스트가 가능한 모듈로 컴파일하여 사용한다.

Setter 접근 제어 (Read only)

저장 프로퍼티를 구현할 때 값을 변경할 수 없도록 구현할 수 있다. (읽기 전용)

struct TrackedString {
    private(set) var numberOfEdits = 0
    var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
}

var stringToEdit = TrackedString()
stringToEdit.value = "This string will be tracked."
stringToEdit.value += " This edit will increment numberOfEdits."
stringToEdit.value += " So will this one."
print("The number of edits is \\(stringToEdit.numberOfEdits)")
// Prints "The number of edits is 3"

private(set)이 지정되지 않았다면 TrackedString 밖에서도 접근이 가능했을 것이다.

'iOS > Swift' 카테고리의 다른 글

[Swift] Frame, Bounds  (0) 2023.01.17
[Swift] 고차함수 (2) - flatMap, compactMap  (0) 2022.12.28
[Swift] 고차함수 (1) - map, filter, reduce  (0) 2022.12.26
[Swift] Protocol (2)  (0) 2022.12.16
[Swift] Protocol (1)  (0) 2022.12.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함