[iOS] Access Control (feat. Module, Source File)

r1verfuture·2022년 4월 14일
0

iOS

목록 보기
17/30

Access Control

  • 접근 제어
  • 다른 소스 파일 및 모듈의 코드에서 코드의 일부에 대한 접근을 제한하는 것 (불필요한 접근 방지)
  • 개별 타입 (class, struct, enum) 뿐 만 아니라 해당 타입에 속하는 프로퍼티, 메소드, 이니셜라이저 및 첨자 (subscripts) 에 대해 특정 접근 레벨을 지정할 수 있다.
  • 프로토콜은 전역 상수, 변수 및 함수처럼 특정 컨텍스트로 제한될 수 있다.
  • Swift 는 코드 내의 개체에 대해 5가지 접근 레벨 (open / public / internal / fileprivate / private) 을 제공한다.
  • open -> public -> internal -> fileprivate -> private 순으로 더 범위가 제한적이다.

Module

  • 코드의 묶음 단위
  • 프레임워크, 라이브러리, 어플리케이션처럼 배포할 코드들의 묶음
  • ex. App Bundle, Framework

Source File

  • 모듈 내의 단일 Swift 소스 코드 파일
  • ex. ViewController.swift

은닉화

  • 객체 외부에서 객체 내의 자료에 접근하는 것을 제한하는 것
  • 데이터를 수정 / 조작하는 동작은 내부에 두고, 접근 (getter) / 설정 (setter) 하는 메소드로 결과만 받는 것
  • 외부에서는 내부적인 움직임을 알 수 없고, 데이터에 어떤 값이 있는지 또는 어떤 변화가 일어나는지 알 수 없다.
  • 단지 데이터의 접근을 메소드 (getter, setter) 를 통해서 결과만 받을 뿐이다.

Open

  • 가장 제한이 적은 접근 레벨
  • 모듈 외부에서도 접근이 가능하다. (개방 접근 수준)
  • 클래스클래스 멤버에만 붙일 수 있다.
  • 모듈 밖의 다른 모듈에서 상속될 수 있다.
  • open 으로 선언된 클래스의 멤버 (프로퍼티, 메소드) 들만이 다른 모듈에서 override 될 수 있다. (ex. UIKit 에 있는 UIViewController 의 정의를 보면 open 클래스로 되어있는 것을 볼 수 있는데, UIViewController 가 open 클래스이기 때문에 어떠한 클래스가 UIViewController 클래스를 상속받으면 viewDidLoad 함수 등을 override 할 수 있는 것이다.)

Public

  • 모듈 외부에서도 접근이 가능하다. (공개 접근 수준)
  • 'open' 과 다르게 해당 클래스를 상속해도 해당 클래스의 멤버들을 override 할 수 없다. (만약에 UIViewController 가 public 클래스로 되어있었다면, UIViewController 클래스를 어떠한 클래스에서 상속받아도 viewDidLoad 함수 등을 override 할 수 없다.)

Internal

  • 하나의 모듈 내부에서만 접근이 가능하다. (내부 접근 수준)
  • 따로 접근 제어자를 붙여주지 않으면 자동으로 붙는 기본 접근 제어자 (굳이 작성할 필요없다.)
  • 같은 모듈 내에서는 어디서든 접근 가능하고, 클래스의 경우에는 어느 곳에서도 해당 클래스를 상속받을 수 있다.

Fileprivate

  • 하나의 스위프트 파일 (.swift) 내에서만 접근이 가능하다. (파일 내부 접근 수준)
  • 다른 언어에서는 하나의 파일에 하나의 클래스 혹은 하나의 타입만 정의하지만, 스위프트에서는 종종 관련이 있기만 하면 같은 파일에 여러 타입을 정의하기도 하기 때문에 필요하다.
  • 해당 소스 파일 외부에서 값이 변경되거나 함수를 호출했을 때 부작용이 생길 수 있는 경우에 사용하면 좋다.

Private

  • 가장 제한이 많은 접근 레벨 (비공개 접근 수준)
  • 정의한 블록 내부에서만 접근이 가능하다.
  • 개체의 사용을 enclosing 선언동일한 파일에 있는 해당 선언의 extension (Swift 3 에서는 불가능했는데, Swift 4 부터는 가능하다.) 으로 제한한다.
  • 단일 정의 내에서만 사용되는 특정 기능 조각의 구현 상세 내역을 숨길 수 있다.
// MARK: [코드 1] 클래스 안에 private 으로 정의된 변수에 접근
class MyName {
	private var name = "r1verfuture"
}

class Test {
	func getMyName() {
    	private let myNameInstance = MyName()
    	print(myNameInstance.name)
    }
}
  • [코드 1] 을 실행하면 에러가 나는데, 그 이유는 Test 클래스에서 MyName 클래스의 private 변수인 'name' 에 접근하려고 했기 때문이다.
// MARK: [코드 2] 동일한 파일에 있는 해당 선언의 extension 에서 private 변수에 접근
class MyName {
	private var name = "r1verfuture"
}

extension MyName {
	func getMyName() {
    	print(name)
    }
}
  • [코드 2] : 같은 소스 파일 내에서 해당 클래스를 extension 한 내부에 private 변수 접근 코드를 써도 에러가 나지 않는다.
  • 하지만, 무조건 같은 소스 파일 내에서만 가능하다.

접근 제어자를 사용할 때 주의해야할 것

  • 상위 요소의 접근 제어 수준보다 높은 수준의 하위 요소는 있을 수 없다. ([코드 3] 참고)
  • 함수의 매개변수로 특정 접근 수준이 부여된 타입이 전달되거나 반환된다면, 그 타입의 접근 수준보다 함수의 접근 수준이 높게 설정될 수 없다. ([코드 4] 참고)
  • 프레임워크를 만들 때는 다른 모듈에서 특정 기능에 접근할 수 있도록 공개 접근 수준으로 지정해주어야 한다.
  • 열거형 (enum) 내부의 각 case 별로 따로 접근 수준을 부여할 수 없고, 각 case 의 접근 수준은 열거형 자체의 접근 수준을 따른다.
// MARK: [코드 3] private 클래스 안에 public 함수 (불가능)
private class AClass {
	public func aFunc() { }
}
// MARK: [코드 4] public 함수에서 private 클래스를 매개변수와 반환값으로 사용 (불가능하고, 에러 발생)
public func aFunc(aClass: AClass) -> AClass {
	return a
}

참고

profile
#iOS #Swift #Developer #Python

0개의 댓글

관련 채용 정보