접근제어는 특정 코드의 접근을 다른 소스파일이나 모듈에서 제한하는 것입니다. 이렇게 접근제어를 함으로써 특정 코드의 세부적인 구현을 감추고 딱 필요한 만큼 공개해 다른 곳에서 사용할 수 있도록 합니다. 접근제어는 클래스, 구조체, 열거형 등 개별 타입에도 적용할 수 있고 그 타입에 속한 프로퍼티, 메소드, 초기자, 서브스크립트에도 적용할 수 있습니다. 프로토콜은 그래서 전역상수, 변수, 함수같이 특정 문맥에 종속됩니다. Swift에서는 기본 접근레벨을 제공해 접근레벨의 처리를 쉽게할 수 있도록 돕습니다. 그래서 사실 단일타겟의 앱에서는 특별히 접근레벨을 전혀 명시하지 않아도 됩니다.
모듈과 소스파일 (Modules and Source Files)
Swift의 접근제어는 모듈과 소스파일에 기반을 두고 있습니다. 모듈은 코드를 배포하는 단일 단위로 하나의 프레임워크나 앱이 이 단위로 배포되고 다른 모듈에서 Swift의 import키워드를 사용해 import될 수 있습니다. Xcode의 각 빌드 타겟은 Swift에서 분리된 단일 모듈로 취급됩니다. 소스파일은 모듈안에 있는 소스파일을 의미합니다. 각 소스파일에 여러 특정 타입을 선언해 사용할 수 있습니다.
접근레벨 (Access Levels)
- Open & Public : Open과 Public 접근자 모두 선언한 모듈이 아닌 다른 모듈에서 사용가능합니다. 두 접근자의 차이점은 Open은 다른 모듈에서 오버라이드와 서브클래싱이 가능하지만 Public 접근자로 선언된 것은 다른 모듈에서는 오버라이드와 서브클래싱이 불가능 합니다.
- Internal : 기본 접근레벨로 아무 접근레벨을 선언하지 않으면 Internal로 간주됩니다. Internal레벨로 선언되면 해당 모듈 전체에서 사용 가능합니다.
- File-private : 특정 엔티티를 선언한 파일 안에서만 사용 가능합니다.
- Private : 특정 엔티티가 선언된 괄호({}) 안에서만 사용 가능합니다.
기본 접근레벨 (Default Access Levels)
위에서 설명한 것과 같이 아무런 접근 레벨을 명시하지 않은 경우 internal을 갖게 됩니다.
단일 타겟 앱을 위한 접근레벨 (Access Levels for Single-Target Apps)
단일 타겟 앱에서는 특별히 접근레벨을 명시할 필요가 없지만 필요에 따라 file-private, private등을 사용해 앱내에서 구현 세부사항을 숨길 수 있습니다.
프레임워크를 위한 접근레벨 (Access Levels for Frameworks)
프레임워크를 개발한다면 public혹은 open으로 지정해서 다른 모듈에서 볼 수 있고 접근 가능하도록 만들어야 합니다.
유닛테스트 타겟을 위한 접근레벨 (Access Levels for Unit Test Targets)
기본적으로 open이나 public으로 지정된 엔티티만 다른 모듈에서 접근 가능합니다. 하지만 유닛테스트를 하는 경우 모듈을 import할때 import앞에 @testable이라는 에트리뷰트를 붙여주면 해달 모듈을 테스트가 가능한 모듈로 컴파일해 사용합니다.
접근제어 문법 (Access Control Syntax)
// 각 접근자를 사용해 클래스와 변수, 상수를 선언한 예는 다음과 같습니다.
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
커스텀 타입 (Custom Types)
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
}
'Swift Language' 카테고리의 다른 글
Swift Language - 25 - 고급 연산자 (Advanced Operators) (0) | 2023.02.06 |
---|---|
Swift Language - 23 - 메모리 안정성 (Memory Safety) (0) | 2023.02.06 |
Swift Language - 22 - 자동 참조 카운트 (Automatic Reference Counting) (0) | 2023.02.06 |
Swift Language - 21 - 제네릭 (Generics) (0) | 2023.02.06 |
Swift Language - 20 - 프로토콜 (Protocols) (0) | 2023.02.06 |