본문 바로가기
iOS/Swift

Swift 접근 제어자 (Access Control)

by 헤콩 2021. 5. 7.
반응형

접근 제어자를 왜 사용할까

오늘은 iOS 개발을 할 때 다양하게 활용할 수 있는 접근 제어자에 대해 알아보려합니다. 규모 있는 어플리케이션을 개발하다보면 객체를 사용하는 입장에서 객체 내부적으로 사용하는 변수나 메서드에 접근함으로써 개발자가 의도하지 못한 오동작을 일으키게 될 수 있습니다. 이런 문제로부터 객체의 로직을 보호하기 위해서 적절한 접근 제어자를 통해 외부의 접근을 허용하거나 차단할 필요가 있습니다.

 

즉, 접근 제어자는 코드를 작성하는 module이나 source file에서 다른 파일에 있는 코드에 대한 접근을 명시적으로 작성하여 관리하는 것입니다.

 

 

여기서 module이란, 하나의 프레임워크를 말합니다. 우리가 Swift로 코드를 짤 때 필요에 따라 적절한 import 키워드를 추가하죠? 그 import 키워드로 추가되는 것들이 module 입니다. UIKit, Foundation 같은 것들 말이죠. 그리고 source file그 module 안에 있는 파일들을 말합니다.

 

 

 

그래서 접근 제어자에는 뭐가 있나

이미지 출처: https://medium.com/ivymobility-developers/access-control-5f88492747b

Swift에는 5가지의 접근 제어자가 있습니다. 각각의 접근 제어자들은 module과 source file을 기준으로 나뉘어지는데요, 아래에 그 5가지 접근 제어자들을 정리해보았습니다. 아래에서 말하는 entity는 접근 제어자가 적용되는 대상을 뜻합니다. (entity: property, method, class, struct 등의 집합들)

 

  • open, public : 프로젝트 내의 모든 module이 해당 entity에 접근할 수 있습니다. 다만, open으로 선언된 entity들은 다른 모듈에서 상속이나 overriding하는게 가능하지만 public불가능합니다!! 그리고 open은 class에만 사용될 수 있습니다.
  • internal : default 접근 제어자로써, 우리가 접근 제어자를 작성하지 않고 entity를 그냥 명시하면 암묵적으로 internal의 속성을 가지게 됩니다. internal은 해당 entity가 작성된 module에서만 접근할 수 있습니다.
  • fileprivate : entity가 작성된 source file에서만 접근할 수 있도록 합니다. 만약 서로 다른 클래스가 같은 파일 안에 있고, fileprivate으로 선언되어 있다면 둘은 접근할 수 있습니다.
  • private : 특정 객체에서만 사용할 수 있도록 하는 가장 제한적인 접근 제어자입니다. fileprivate와 달리 같은 파일 안에 있어도 서로 다른 객체가 private으로 선언되어 있다면 둘은 서로 접근할 수 없습니다.

 

 

예외적인 상황이 있다면?

Unit Test를 할 때는 @testable 키워드로 모듈을 import하여 public과 open이 아닌 entity들을 사용할 수 있도록 해줍니다.

 

@testable import {target_name}

 

특정 Unit test의 파일 상단에 위처럼 선언을 하면 해당 모듈의 entity를 internal 형태로 사용할 수 있도록 해줍니다.

 

 

 

 

또한, Swift에서는 Getter와 Setter에 서로 다른 접근제어자를 적용할 수 있습니다. Setter를 Getter보다 더 제한적으로 설정할 수 있는데요, 이는 getter와 setter를 모두 따로 작성하지 않아도 되는 매우 큰 장점을 제공합니다 :)

 

private(set) var name: String

 

만약 다른 조건 없이 위와 같이 변수를 작성한다면, name의 getter는 internal이 되고, setter는 private이 됩니다!

 

 

 

아주아주 만약에 아래와 같은 코드가 있다면?

 

public struct Car {
    fileprivate(set) var engine: String
}

 

engine의 getter는 자신이 속한 struct를 따라 public이 되지만, setter는 fileprivate이 됩니다.

 

 

 

 

Reference

반응형

댓글