접근 제어자 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
* 참고 : 은닉화(Hiding)란?
- 객체지향 개발에서 외부로부터 데이터를 보호하기 위해, 객체 외부에서 객체 내 자료로의 접근을 제한하고, 데이터를 수정하거나 조작하는 동작은 접근자(getter, setter)를 통해 결과만 받는 것. 외부에서의 직접 접근은 막고 메서드를 통해 간접 접근할 수 있도록.
예를 들어 public class 안의 변수 int hour가 0~23 사이의 값을 가져야할 때,
변수의 접근 제어자를 private 으로 하여 외부에서 직접 접근하지 못하도록 하고,
setHour 메서드를 통해 간접적으로 접근할 수 있도록 하여 값을 보호할 수 있다.
public class Time {
private int hour;
private boolean isValidHour(int hour) { //클래스 내부에서만 사용되는 유효성 확인 메서드
return (hour < 0 || hour > 23);
}
public void setHour(int hour) { //유효성 확인 후 변수 설정
if isValidHour(hour) return;
this.hour = hour;
}
public int getHour() { return hour; }
}
Time().hour = 25; 와 같이 값을 직접 변경하는 게 아니라
Time().setHour(21); Time.getHour(); 이런 식으로 get set 메서드를 통한 간접 접근이 가능하다.
참고 : youtube - 남궁성의 정석코딩
Access Control (접근 제어)
다른 소스파일 및 모듈의 코드에서, 코드의 일부에 대한 액세스(접근)을 제한하는 것.
individual types (classes, structures, enumerations) 뿐 아니라 해당 타입에 속하는 properties, methods, initializers and subscripts 에 대해 특정 접근 레벨을 지정할 수 있다.
Modules and Source Files
Swift 접근 제어 모델은 모듈 및 소스 파일의 개념을 기반으로 한다.
* 모듈 : 시스템(혹은 프로그램)이나 제품 등에서 개별적인 기능이나 역할을 가진 부품, 요소 등을 칭한다 - 나무위키
Xcode의 각 build target(예: app bundle 또는 framework)은 Swift에서 별도의 모듈로 처리되는데, 보통 import로 불러와 사용하는 것들을 모두 모듈이라고 이해하면 될듯?
소스 파일은 말그대로 Swift 소스 코드 파일. 각 소스 파일 마다 individual types 를 정의하는 것이 일반적이지만, 하나의 소스 파일에는 여러 타입, 함수 등에 대한 정의가 포함될 수 있다.
Access Levels
Swift는 코드 내의 엔티티에 대해 5가지 제어 단계를 제공한다. open - public - internal - fileprivate - private
• open, public (개방, 공개 접근수준)
엔티티가 정의된 모듈의 모든 소스 파일 내에서 사용 가능 + 정의한 모듈을 가져오는 다른 모듈의 소스 파일에서도 사용 가능.
일반적으로 공용 인터페이스를 지정할 때 open / public 접근을 사용.
open 접근은 클래스 및 클래스 멤버에만 적용 가능하며, (struct와 enum은 public 부터 가능)
모듈 외부의 코드에서도 서브클래싱(subclass) 및 재정의(override)가 허용된다는 점이 public과의 차이.
• internal (내부) - default access level
엔티티가 정의된 모듈의 모든 소스 파일 내에서 사용할 수 있지만, 해당 모듈 외부의 소스 파일에서는 사용 불가.
일반적으로 앱 또는 프레임워크의 내부 구조를 정의할 때 internal 사용.
모든 요소의 기본 지정 접근수준 (따로 표기해줄 필요 없음)
• fileprivate (파일외부 비공개)
엔티티가 정의된 소스파일 내부에서만 사용 가능
해당 소스파일 외부에서 값이 변경되너나 함수 호출하면 부작용이 생길 수 있는 경우 사용하면 좋음
• private (비공개)
엔티티를 정의하고 구현한 범위 내에서만 사용 가능
Access Levels for Single-Target Apps
간단한 Single-Target 앱을 작성할 때는 앱 모듈 외부에서 코드를 사용할 필요가 없기 때문에 굳이 따로 액세스 수준을 지정할 필요 없이 기본값 internal을 사용하거나, 필요에 따라 코드 일부를 fileprivate 또는 private으로 작성할 수 있다.
Access Levels for Frameworks
프레임워크를 개발할 때, 프레임워크 API(application programming interface)로 사용될 공용 인터페이스(public-facing interface)는 다른 모듈에서 보고 접근할 수 있도록 open / public 으로 작성한다.
* API (application programming interface 응용 프로그램 프로그래밍 인터페이스) - 컴퓨터나 컴퓨터 프로그램(소프트웨어) 사이의 연결
UI (user interface 사용자 인터페이스) - 사람과 컴퓨터 사이의 연결
Access Levels for Unit Test Targets
단위 테스트 타겟이 있는 앱을 작성할 때는, 테스트를 위해 해당 모듈에서 사용할 수 있도록 작성되어야 한다.
기본적으로는 open / public으로 표시된 엔티티만 다른 모듈에 엑세스할 수 있지만, unit test target은 @testable 속성을 표시해주면 모든 internal 엔티티에 접근이 가능하다.
Subclassing
서브클래스는 슈퍼클래스보다 더 제한적이거나 같은 접근 수준만 가질 수 있다.
class A { }
public class B : A { //Error }
위 처럼 서브클래스가 슈퍼클래스보다 더 높은 접근 레벨을 가질 수는 없지만,
아래처럼 더 제한적인 접근 수준은 가질 수 있다.
public class A { }
internal class B : A { }
override를 사용하면, 상속된 클래스 멤버가 슈퍼클래스 버전보다 덜 제한적인 접근 수준을 가질 수도 있다.
public class A {
filepivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
}
Getters and Setters
setter에 해당 getter보다 제한적인 접근 수준을 부여하여 해당 변수, 프로퍼티 또는 서브스크립트의 읽기/쓰기 범위를 제한할 수 있다.
struct TrackedString {
private(set) var numberOfEdits = 0
var value: String = "" {
didSet {
numberOfEdits += 1
}
}
}
private(set) 을 변수 앞에 붙여주면, 해당 변수는 선언된 구조체 코드 내에서만 설정(set)할 수 있다는 것을 의미.
즉, 외부에서도 접근은 가능하여 읽을 수는 있지만 set만 private.
다른 소스 파일에서
var trackedString = TrackedString()
print(trackedString.numberOfEdits)
이렇게 값을 읽어오는 건 가능하지만
trackedString.numberOfEdits = 10 이렇게 직접 값을 넣으려고 하면 에러가 난다.
Setter만 더 낮은 접근수준을 갖도록 제한할 수 있다.
private(set) var property: Type
접근(getter)은 public이지만 설정(setter)은 private으로 할 수도 있다.
public private(set) var property: Type
참고 : Swift 문서 - Access Control, ZeddiOS,
'Swift iOS 앱 개발 > Swift' 카테고리의 다른 글
[Swift] Class / Struct / Enum Types (0) | 2022.05.12 |
---|---|
About Swift (0) | 2022.05.12 |
[Swift iOS] UITextView set placeholder (0) | 2021.12.09 |
[Swift iOS] detect UITableView scroll to bottom (0) | 2021.12.08 |
[Swift iOS] keyboard top toolbar 추가하기 (0) | 2021.11.11 |