본문 바로가기

iOS/Swift

Access Control(접근제어자)

안녕하세요!! 정~말 오랜만에 글을 씁니다!!!

한동안 이래저래.. 나태하게 지냈는데 다시 맘잡구 천천히 시작해보겠습니다!

 

오늘은 비교적 간단한 내용을 가져왔는데여.

바로 접근제어자입니다.

 

Swift 접근제어자에 대해 정리해 보겠습니다.

 

저는 앱을 만들때 보면 접근 제어자를 default 아니면 private 정도만 쓰게 되더라구요.

 

접근제어자를 사용하는 이유는 모듈, 소스파일 등 요소의 접근을 제어하기 위해서잖아요? (객체지향의 은닉화 구현.. 뭐 그런거?)

뭐 접근을 제어해서 상세 구현을 숨기고, 불필요한 접근을 막아서 코드를 좀 더 좋게 만들 수 있따 그런거잖아여.

이렇게 두루뭉실하게만 알고 있기도 하고, 너무 의식하지 않고 생각없이 사용해온 것 같아서 좀 더 세분화해서 접근 관리를 할 필요가 있지 않나라는 생각에 한번 정리해 보기로 했습니다.

모듈, 소스파일(Modules and Source FIles)

접근제어자에 대해 알아보기 전 모듈소스파일 개념에 대해서 살펴보겠습니다.

 

module 은 하나의 프레임워크를 의미합니다. → import 키워드로 추가하는 거가 다 모듈인거심!

UIKit, SwiftUI, Foundation, Combine 등등 다 import해서 사용하잖아요?? 얘네가 다 모듈입니다.

프로젝트 하위에 보면 target도 있잖아요(1개 이상)? 걔네도 다 모듈입니다.

이러한 module 내부의 파일들이 source file이구요(~~.swift 파일들).

 

Swift에서 접근 제어자는 총 5개를 제공합니다.

open, public, internal, fileprivate, private 이 있습니다.

접근 제어자를 분류하는 기준은 module과 sourcefile의 접근 권한입니다.

 

보기에 앞서 접근제어자를 사용할 수 있는 모든 대상(property, method, class, struct)는 entity로 칭하도록 하겠습니다.

아래에서 하나씩 살펴보도록 하겠습니다!

open

접근 제어자 중 가장 넓은 범위의 접근제어자 입니다.

  • 프로젝트 내의 모든 module의 entity에 접근 가능할 수 있는 제어자
  • 외부 모듈에서 내부 모듈의 클래스, 메서드를 subclass, overriding할 수 있습니다.

그래서 보통 라이브러리를 만들 때 많이 사용한다고 합니다.

(open으로 선언된 클래스, 메서드를 상속, 재사용이 가능하기 때문!)

 

아직 라이브러리 제작 경험은 없는데 추후에 한번 해봐야겠네요.

public

  • 프로젝트 내의 모든 module의 entity에 접근 가능할 수 있는 제어자(open과 공통점)
  • 외부 모듈에서 내부 모듈의 클래스, 메서드를 subclass, overriding할 수 없음!(open과 차이점)

public은 open과 마찬가지로 프로젝트 내 모든 entity에 접근할 수 있습니다.

차이점으로는 외부 모듈과의 subclass이나 overriding이 불가능하다는 점입니다.

internal

  • Entity가 작성된 module 내부에서만 접근할 수 있음
  • Default 접근 제어자로써, 아무 접근제어자를 작성하지 않을경우 기본적으로 적용되는 제어자입니다.

fileprivate

  • Entity가 작성된 source file에서만 접근할 수 있음.

예를 들어, 두 개의 클래스가 fileprivate으로 선언되어 있고, 같은 source file 내부에 있다면 둘은 접근이 가능함.

다른 source file에 위치해 있다면 접근이 불가능합니다.

private

접근 제어자 중 가장 좁은 범위의 제어자

  • 동일한 source file 내부여도 서로 다른 객체가 private으로 선언되었다면 접근이 불가능함.

간단하게 살펴보니 open에서 private으로 갈수록 접근 범위가 좁아진다는 것을 확인할 수 있습니다.

그리고 그 범위는 각 module과 source file이 기준이 된다는 점을 확인할 수 있었구요.

 

앞으로는 무턱대고 interal, private을 사용할 게 아니라 entity의 사용 범위를 한번 생각한 후, 적절한 제어자를 찾아 사용해야겠습니다 ~_~,,,

참고 사항

위와 같은 방법으로 용도에 맞게 최소한의 범위로 접근 제어자를 사용할 수 있었는데요.

 

하지만 사용할 때 주의해야 할 몇가지 사항이 있는데 그 내용은 다음과 같습니다.

  • 내부의 entity는 외부의 entity보다 넓은 범위의 접근 제어자를 가질 수 없습니다.
  • 또한 외부 타입의 접근 제어 수준이 멤버의 접근 제어 수준에도 영향을 끼침.

글만 보면 이해가 좀 어려울 수 있는데, 아래 예시 코드를 통해 살펴보겠습니다.

 

public class SomePublicClass {                  // 명시적 public class
    public var somePublicProperty = 0            // 명시적 public class member
    var someInternalProperty = 0                 // 암묵적 internal class member
    fileprivate func someFilePrivateMethod() {}  // 명시적 file-private class member
    private func somePrivateMethod() {}          // 명시적 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
}

각 class들은  public, internal, fileprivate, private의 접근 범위를 가지고 있습니다.

SomePublicClass는 명시적으로 puilc의 접근 제어 범위를 가지고 있음을 나타냈습니다.

내부의 프로퍼티들은 public보다 넓은 범위(open)의 접근 범위를 가질 수 없으며,

명시적으로 접근 범위를 나타내지 않은 경우, 암묵적으로 internal의 접근 제어 범위를 가짐을 확인할 수 있습니다.

 

SomeFilePrivateClass를 살펴보면,

접근 제어를 명시하지 않았을 경우, 암묵적으로 fileprivate의 범위를 가짐을 확인했습니다!

 

여기서 우리는 아래와 같은 내용을 확인할 수 있고, 주의해야 합니다.

 

internal 보다 넓은 접근 제어일 경우, 접근 제어를 명시하지 않을 경우 암묵적으로 internal의 범위를 가지고,
그 외(fileprivate, private)의 경우 명시하지 않을 경우 암묵적으로 외부의 범위를 따라가는구나!

 

또 다른 참고사항으로,

 

Getter와 Setter는 서로 다른 접근 제어자를 명시할 수 있음.

Setter를 Getter보다 더 제한적으로 설정 가능(반대는 불가)

private(set) var property: String

위의 경우 Getter는 internal, Setter는 private으로 접근 제어가 명시됨.

 

 

공식문서를 통해서 한번 공부해 봤는데, 접근 제어 기준과 접근 제어자에 따른 내부 멤버 접근 변화까지 확인할 수 있었습니다!

앞으로는 무작정.. private 쓰는게 아니라 접근 제어 범위에 대해서도 좀 생각해보면서 개발을 해봐야겠습니다!

 

오랜만에 정리하고 글을 쓰려고 하니까.. 힘드네요 ㅎㅎ ^^;;...

다시 조금씩 습관을 들여봐야 할 것 같아요..

 

읽어주셔서 감사합니다! 틀린 내용이나 추가할 내용이 보일 경우 알려주시면 감사하겠습니다!

더 좋은 내용으로 또 오겠습니다!

 

작성한 내용 말고도 더 자세한 내용은 아래의 공식 문서를 참조해주시기 바랍니다.

 


접근 제어 (Access Control) | Swift

 

접근 제어 (Access Control) | Swift

선언, 파일, 그리고 모듈에 의해 코드의 노출을 관리합니다. 접근 제어 (Access control) 는 다른 소스 파일과 모듈에서 코드 접근에 대해 제한합니다. 이 기능은 코드의 구현 세부를 숨기고 해당 코

bbiguduk.gitbook.io

 

'iOS > Swift' 카테고리의 다른 글

Concurrency - 기초  (5) 2024.10.13
Type Erasure, Opaque Type  (0) 2024.07.03
[weak self] 왜 쓸까!!  (1) 2024.01.15
Metatype(.self, .Type, .Protocol)  (1) 2023.11.08
Swift Xcode 프로젝트명 바꾸기  (0) 2023.08.01