
Swift가 제공하는 5가지 접근 제어 단계 형식을 통해 다른 소스파일 및 모듈에서의 접근을 제한할 수 있다. 본 게시글 내에서 함수, 메소드, 프로퍼티, 이니셜라이저 등을 간결하게 엔티티라고 표현할 것임.
접근 레벨 (밑으로 갈수록 접근 레벨이 낮아진다고 표현)
- open: 외부 모듈에서도 접근 가능, 서브클래싱 및 오버라이딩 가능
- public: 외부 모듈에서 접근 가능. 단, 서브클래싱 및 오버라이딩 불가능
- internal: 외부 모듈에서 접근 불가능, 해당 모듈의 모든 소스에서 접근 가능. 접근 단계 디폴트값.
- file-private: 특정 엔티티 선언한 파일 안에서만 접근 가능
- private: 해당 엔티티를 선언한 괄호{} 안에서만 접근 가능
👉🏻 모듈-> 하나의 앱 단위, 소스파일-> xcode프로젝트 안의 한 파일
접근 레벨이 더 낮은 단계의 엔티티 안에서 높은 단계의 엔티티가 정의될 수 없음. 이론상 정의된다고 해도 낮은 단계의 엔티티의 수준을 넘어 사용될 수 없기 때문.
같거나 낮은 단계는 사용 가능. 디폴트는 internal.
다음과 같이 사용 가능하다.
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
}
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 이러면 컴파일 오류
}
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// 이렇게 함수 앞에도 선언해줘야 오류 X
}
서브클래스는 슈퍼클래스보다 높은 단계의 접근제어 레벨을 설정할 수 없다. 그러나 다음과 같이 오버라이딩 하면 가능.
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
super.someMethod() //이렇게 설정할 수 있기 때문에 사용 가능
}
게터와 세터는 기본적으로 변수나 상수, 프로퍼티와 같은 수준의 접근단계를 가진다. 이보다 더 낮게는 설정 가능.
struct TrackedString {
private(set) var numberOfEdits = 0 //다음과 같이 더 낮은 단계의 접근레벨과 (set), (get) 등을 붙여줌
var value: String = "" {
didSet {
numberOfEdits += 1
}
}
}
위 예제에서, private(set)이 없었다면 numberOfEdits가 모듈 밖에서도 사용이 가능했을 것(default->internal). 그러나 private(set)으로 설정해줬기 때문에 TrackedString 안에서만 접근 가능해졌다.
이후 내용은 제네릭 등 더 공부하고 나서 추가.
🌏 참고사이트
Swift Language Guide