접근 제어란?
프로퍼티, 타입, 함수 등에 접근 제어를 적용할 수 있는 코드의 다양한 부분은 이후부터 “엔티티” 라고 부름
import
키워드를 사용해 다른 모듈에서 가져올 수 있음코드의 모든 엔티티는 명시적으로 접근 수준을 지정하지 않으면 Internal의 기본 접근 수준을 가진다.
간단한 단일 타겟 앱의 코드는 일반적으로 앱 내에 자체적으로 포함됨. 앱의 모듈 외부에서 사용할 수 있도록 만들 필요 없음. 그러나 앱의 모듈 내에서 (다른 코드에서 구현 세부정보를 가리기 위해) file-private, private로 코드의 부분을 표기할 수 있음
프레임워크를 개발할 때 다른 모듈에서 보고 접근할 수 있게 하게 위해 공용 인터페이스를 open, public으로 표시함. 프레임워크 용 애플리케이션 프로그래밍 인터페이스 또는 API.
유닛 테스트 타겟과 함께 앱을 작성할 때 앱의 코드는 테스트를 위해 해당 모듈에서 사용할 수 있어야 함.
기본적으로 open, public 엔티티만 다른 모듈에서 접근할 수 있음. 그러나 모듈에 대한 가져오기 선언을 @testable
속성으로 표시하고 테스트를 활성화하여 컴파일하면 유닛 테스트 타겟은 모든 내부 엔티티에 접근할 수 있음.
public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
// 따로 지정하지 않으면 기본은 internal
class SomeInternalClass {} // implicitly internal
let someInternalConstant = 0 // implicitly internal
‼️ Public 타입은 기본적으로 internal 멤버를 가짐!
public으로 하려면 명시적으로 표시해야 함
public class SomePublicClass { // explicitly public class
public var somePublicProperty = 0 // explicitly public class member
var someInternalProperty = 0 // implicitly internal class member
fileprivate func someFilePrivateMethod() {} // explicitly file-private class member
private func somePrivateMethod() {} // explicitly private class member
}
class SomeInternalClass { // implicitly internal class
var someInternalProperty = 0 // implicitly internal class member
fileprivate func someFilePrivateMethod() {} // explicitly file-private class member
private func somePrivateMethod() {} // explicitly private class member
}
fileprivate class SomeFilePrivateClass { // explicitly file-private class
func someFilePrivateMethod() {} // implicitly file-private class member
private func somePrivateMethod() {} // explicitly private class member
}
private class SomePrivateClass { // explicitly private class
func somePrivateMethod() {} // implicitly private class member
}
튜플 타입에 대한 접근 수준은 해당 튜플에서 사용되는 모든 타입 중 가장 제한적인 접근 수준을 따라감.
함수 타입에 대한 접근 수준은 함수의 파라미터 타입과 반환 타입 중 가장 제한적인 접근 수준을 따라감.
열거형의 개별 케이스는 열거형과 같은 접근 수준을 받음. 개별 열거형 케이스에 대해 다른 접근 수준을 지정할 수 없음.
열거형 정의의 모든 원시값 또는 연관된 값에 사용되는 타입은 열거형의 접근 수준보다 높은 접근 수준을 가져야 함.
중첩된 타입의 접근 수준은 포함한 타입이 public이 아닌 경우 포함한 타입과 동일함.
public 타입 내에 정의된 중첩된 타입은 자동으로 internal 접근 수준을 가짐.
현재 접근 컨텍스트에서 접근할 수 있고 하위 클래스와 동일한 모듈에 정의된 모든 클래스를 하위 클래스로 지정할 수 있음. 다른 모듈에 정의된 모든 open 클래스도 하위 클래스로 지정할 수 있음.
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
}
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {
super.someMethod()
}
}
var
또는 subscript
전에 fileprivate(set)
, private(set)
, 또는 internal(set)
을 작성하여 더 낮은 접근 수준을 할당기존 프로토콜에서 상속하는 새로운 프로토콜을 정의한다면 새로운 프로토콜은 상속된 프로토콜과 최대 동일한 접근 수준을 가질 수 있다.
확장 안에 코드가 기존 타입의 선언의 부분으로 작성된 것처럼 동작
제너릭 타입 또는 함수 자체의 접근 수준과 해당 타입 파라미터에 대한 모든 타입 제약조건의 접근 수준의 최소
타입 별칭은 별칭이 지정된 타입의 접근 수준보다 작거나 같은 접근 수준을 가질 수 있음