접근제어
- 코드끼리 상호작용을 할 때 파일 간 또는 모듈 간에 접근을 제한할 수 있는 기능
- 접근제어를 통해 코드의 상세 구현은 숨기고 허용된 기능만 사용하는 인터페이스를 제공할 수 있다.
접근제어의 필요성
- 외부에서 보거나 접근하면 안되는 코드가 있는 경우 꼭 필요한 부분만 제공해야 하는데 전체 코드가
노출될 가능성이 있을 때 접근제어를 이용한다.
모듈
- 모듈은 배포할 코드의 묶음 단위이다.
- 통상 하나의 프레임워크나 라이브러리, 애플리케이션이 모듈 단위가 될 수 있다.
- 스위프트에서는 import 키워드를 사용해 불러온다.
소스파일
- 소스파일은 하나의 스위프트 소스 코드 파일을 의미한다.
- 스위프트에서 보통 파일 하나에 타입 하나만 정의하지만, 때로는 소스파일 하나에 여러 타입이나 함수 등
많은 것을 정의하거나 구현할 수도 있다.
접근수준
- 접근제어는 접근수준 키워드를 통해 구현할 수 있다.
- 각 타입에 특정 접근수준을 지정할 수 있고, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도
접근수준을 지정할 수 있다. - 접근수준을 명시할 수 있는 키워드는 open, public, internal, fileprivate, private 다섯 가지가 있다.
- 스위프트의 접근 수준은 기본적으로 모듈과 소스파일에 따라 구분한다.
접근 수준 | 키워드 | 범위 | 비고 |
개방 접근수준 | open | 모듈 외부까지 | 클래스에서만 사용 |
공개 접근수준 | public | 모듈 외부까지 | |
내부 접근수준 | internal | 모듈 외부 | |
파일외부비공개 접근수준 | fileprivate | 파일 내부 | |
비공개 접근수준 | private | 기능정의 <-> 내부 |
공개 접근수준 - public
- public 키워드로 접근수준이 지정된 요소는 어디서든 쓰일 수 있다.
- 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 쓰인다.
개방 접근수준 - open
- open 접근수준은 public 접근수준 이상으로 높은 접근수준이며, 클래스와 클래스의 멤버에서만 사용할 수 있다.
공개 접근수준과 차이점
- 개방 접근수준을 제외한 다른 모든 접근수준의 클래스는 그 클래스가 정의된 모듈에서만 상속할 수 있다.
- 개방 접근수준을 제외한 다른 모든 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 안에서만
재정의할 수 있다. - 개방 접근수준의 클래스는 그 클래스가 정의된 모듈 밖의 다른 모듈에서도 상속할 수 있다.
- 개방 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 밖의 다른 모듈에서도 재정의(override)할 수 있다.
- 클래스를 개방 접근수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 부모클래스로 사용 하겠다는 목적으로
클래스를 설계하고 코드를 작성했음을 의미한다.
내부 접근수준 - internal
- 기본적으로 모든 요소에 암묵적으로 지정하는 기본 접근수준이다.
- 내부 접근수준으로 지정된 요소는 소스파일이 속해 있는 모듈 어디에서든 쓰일 수 있다.
- 다만 그 모듈을 가져가 쓰는 외부 모듈에서는 접근할 수 없다.
파일외부비공개 접근수준 - fileprivate
- 파일외부비공개 접근수준으로 지정된 요소는 그 요소가 구현된 소스파일 내부에서만 사용할 수 있다.
- 해당 소스파일 외부에서 값이 변경되거나 함수를 호출하면 부작용이 생길 수 있는 경우에 사용하면 좋다.
비공개 접근수준 - private
- 비공개 접근수준은 가장 한정적인 범위이다.
- 비공개 접근수준으로 지정된 요소는 그 기능을 정의하고 구현한 범위 내에서만 사용할 수 있다.
- 심지어 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없다.
접근제어 구현 참고사항
- 모든 타입에 적용되는 겁근수준의 규칙은 상위 요소보다 하위 요소가 더 높은 접근 수준을 가질 수 없다.
- 예시로 비공개 접근수준으로 정의한 구조체 내부의 프로퍼티로 내부수준이나 공개수준을 갖는
프로퍼티를 정의할 수 없다.
- 예시로 비공개 접근수준으로 정의한 구조체 내부의 프로퍼티로 내부수준이나 공개수준을 갖는
private와 fileprivate
- 같은 파일 내부에서 private와 fileprivate는 사용할 때 차이가 있다.
- fileprivate 접근수준으로 지정한 요소는 같은 파일 어떤 코드에서도 접근이 가능하지만
private 접근수준으로 지정한 요소는 같은 파일 내부에 다른 타입의 코드가 있더라도 접근이 불가능하다.- private의 경우 자신을 확장하는 익스텐션 코드가 같은 파일에 존재하는 경우에는 접근할 수 있다.
public struct SomeType {
private var privateVariable = 0
fileprivate var fileprivateVariable = 0
}
// 같은 타입의 익스텐션에서는 private 요소에 접근 가능
extension SomeType {
public func publicMethod() {
print("\(self.privateVariable), \(self.fileprivateVariable)")
}
private func privateMethod() {
print("\(self.privateVariable), \(self.fileprivateVariable)")
}
fileprivate func fileprivateMethod() {
print("\(self.privateVariable), \(self.fileprivateVariable)")
}
}
struct AnotherType {
var someInstance: SomeType = SomeType()
mutating func someMethod() {
// public 접근수준에는 어디서든 접근 가능
self.someInstance.publicMethod() // 0, 0
// 같은 파일에 속해 있는 코드이므로 fileprivate 접근수준 요소에 접근 가능
self.someInstance.fileprivateVariable = 100
self.someInstance.fileprivateMethod() // 0, 100
// 다른 타입 내부의 코드이므로 private 요소에 접근 불가! 오류!
// self.someInstance.privateVariable = 100
// self.someInstance.privateMethod()
}
}
var anotherInstance = AnotherType()
anotherInstance.someMethod()
읽기 전용 구현
- 구조체 또는 클래스를 사용하여 저장 프로퍼티를 구현할 때 허용된 접근수준에서 프로퍼티 값을 가져갈 수 있는데
값을 변경할 수 없도로 구현하고 싶을 때 설정자(Setter)만 더 낮은 접근수준을 갖도록 제한할 수 있다. - 요소의 접근수준 키워드 뒤에 {접근수준}(set) 처럼 표현한다.
- 설정자(Setter)접근수준 제한은 프로퍼티, 서브스크립트, 변수 등에 적용될 수 있고, 해당 요소의 접근 수준보다
같거나 낮은 수준으로 제한해 주어야 한다.
public struct SomeType {
// 비공개 접근수준 저장 프로퍼티 count
private var count: Int = 0
// 공개 접근수준 저장 프로퍼티 publicStoredProperty
public var publicStoredProperty: Int = 0
// 공개 접근수준 저장 프로퍼티 publicGetOnlyStoredProperty
// 설정자는 비공개 접근수준
public private(set) var publicGetOnlyStoredProperty: Int = 0
// 내부 접근수준 연산 프로퍼티 internalComputedProperty
internal var internalComputedProperty: Int {
get {
return count
}
set {
count += 1
}
}
// 내부 접근수준 저장 프로퍼티 internalGetOnlyComputedProperty
// 설정자는 비공개 접근수준
internal private(set) var internalGetOnlyComputedProperty: Int {
get {
return count
}
set {
count += 1
}
}
}
var someInstance: SomeType = SomeType()
// 외부에서 접근자, 설정자 모두 사용 가능
print(someInstance.publicStoredProperty) // 0
someInstance.publicStoredProperty = 100
// 외부에서 접근자만 사용 가능
print(someInstance.publicGetOnlyStoredProperty) // 0
//someInstance.publicGetOnlyStoredProperty = 100 // 오류 발생
// 외부에서 접근자, 설정자 모두 사용 가능
print(someInstance.internalComputedProperty) // 0
someInstance.internalComputedProperty = 100
// 외부에서 접근자만 사용 가능
print(someInstance.internalGetOnlyComputedProperty) // 1
//someInstance.internalGetOnlyComputedProperty = 100 // 오류 발생
'iOS-Study' 카테고리의 다른 글
iOS Study : 7주차 - Swift 공식 문서 정리 (0) | 2022.12.24 |
---|---|
iOS Study : 7주차 - 프로토콜 지향 프로그래밍(P.O.P) (0) | 2022.12.24 |
iOS Study : 6주차 - Simple Value / Control Flow / Functions and Closures / Object and Classes (0) | 2022.12.10 |
iOS Study : 6주차 - 오류처리 / 고차함수 (0) | 2022.12.10 |
iOS Study : 6주차 - 타입 확장(프로토콜, 익스텐션) (0) | 2022.12.10 |