Access Control
은 특정 코드의 접근을 다른 소스파일이나 모듈에서 제한하는 것
Access Control은 클래스, 구조체, 열거형 등 개별 타입에도 적용 가능하고, 프로퍼티, 메소드, 초기자, 서브스크립트에도 적용할 수 있다.
Swift의 접근제어는 모듈과 소스파일에 기반을 두고 있다.
모듈은 코드를 배포하는 단일 단위로 하나의 프레임워크나 앱이 이 단위로 배포되고 다른 모듈에서 Swift의 import키워드를 사용해 import될 수 있다.
Swift에서는 5개의 접근레벨을 제공한다.
두 접근자 모두 선언한 모듈이 아닌 다른 모듈에서 사용이 가능.
Open
키워드는 다른 모듈에서 오버라이드와 서브클래싱이 가능하지만,
Public
으로 선언된 것은 다른 모듈에서 오버라이드와 서브클래싱이 불가능하다.
Default한 접근레벨로 해당 모듈 전체에서 사용 가능하다.
특정 엔티티를 선언한 파일 안에서만 사용 가능
특정 엔티티가 선언된 괄호({})안에서만 사용 가능
접근 레벨은 더 낮은 레벨을 갖고 있는 다른 엔티티를 특정 엔티티에 선언해 사용할 수 없다는 일반 가이드 원칙을 따릅니다.
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)
아무것도 명시하지 않을 경우 internal
file-private
, private
등을 사용해 구현 세부사항을 숨길 수 있다.
프레임워크를 개발한다면 public
혹은 open
으로 지정해서, 다른 모듈에서 볼 수 있고 접근 가능하게 만들어야 한다.
기본적으로 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
}
}
}
초기자의 접근레벨은 타입의 레벨과 같거나 낮습니다.