Swift) 접근 제어(Access Control)

Havi·2021년 1월 17일
0

Swift기초

목록 보기
15/19

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

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

모듈과 소스파일

Swift의 접근제어는 모듈과 소스파일에 기반을 두고 있다.

모듈은 코드를 배포하는 단일 단위로 하나의 프레임워크나 앱이 이 단위로 배포되고 다른 모듈에서 Swift의 import키워드를 사용해 import될 수 있다.

Access Levels

Swift에서는 5개의 접근레벨을 제공한다.

  1. Open & Public

두 접근자 모두 선언한 모듈이 아닌 다른 모듈에서 사용이 가능.
Open 키워드는 다른 모듈에서 오버라이드와 서브클래싱이 가능하지만,
Public으로 선언된 것은 다른 모듈에서 오버라이드와 서브클래싱이 불가능하다.

  1. Internal

Default한 접근레벨로 해당 모듈 전체에서 사용 가능하다.

  1. File-private

특정 엔티티를 선언한 파일 안에서만 사용 가능

  1. Private

특정 엔티티가 선언된 괄호({})안에서만 사용 가능

접근레벨 가이드 원칙

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

  • public 변수는 다른 internal, file-private 혹은 private 타입에서 정의될 수 없다.
private struct A {
    public var a: Int // Constant must be declared private or fileprivate because its type 'A' uses a private type
}

let test = A(a: 100)

print(test.a)

기본 Access Level

아무것도 명시하지 않을 경우 internal

단일 타켓 앱을 위한 Access Level

file-private, private등을 사용해 구현 세부사항을 숨길 수 있다.

프레임워크를 위한 Access Level

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

유닛 테스트를 위한 Access Level

기본적으로 open이나 public으로 지정된 엔티티만 다른 모듈에서 접근 가능

하지만 유닛테스트를 하는 경우 모듈을 import할 때 @testable 어트리뷰트를 붙일 경우 테스트 가능한 모듈로 컴파일

커스텀 타입

커스텀 클래스에 특정 접근레벨을 지정하면, 클래스 안의 프로퍼티와 리턴 타입의 접근레벨은 클래스 레벨의 접근 권한만 사용할 수 있습니다.

fileprivate class SomeFilePrivateClass {        // explicitly file-private class
    func someFilePrivateMethod() {}              // implicitly file-private class member
    private func somePrivateMethod() {}          // explicitly private class member
}

튜플 타입

하나는 internal, 하나는 private일 경우 더 낮은 접근 레벨을 가진다.

함수 타입

최소의 접근레벨로 계산되어 사용

func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here
}

SomePrivateClass가 private 이기 때문에 internal로 선언될 수 없음!

열거형 타입

public enum CompassPoint {
    case north
    case south
    case east
    case west
}

각각의 enum의 case는 public 접근레벨을 가짐

서브클래싱

서브 클래스는 슈퍼 클래스보다 더 높은 접근 레벨을 가질 수 없다.

public class A {
    fileprivate func someMethod() {}
}

// B는 public보다 낮은 접근레벨을 가지고 있어야 한다.
open class B: A { // Superclass 'A' of open class must be open
    override internal func someMethod() {}
}

상수, 변수, 프로퍼티 그리고 서브스크립트

상수, 변수, 프로퍼티 그리고 서브스크립트의 게터와 세터는 자동으로 해당 상수, 변수, 프로퍼티 그리고 서브스크립트가 갖는 접근레벨을 동일하게 갖습니다.

// TrackedString에서만 set 할 수 있고, 외부에서 set 불가.
struct TrackedString {
    private(set) var numberOfEdits = 0
    var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
}

초기자

초기자의 접근레벨은 타입의 레벨과 같거나 낮습니다.

profile
iOS Developer

0개의 댓글