Danny의 iOS 컨닝페이퍼
article thumbnail
Published 2022. 12. 27. 20:29
[iOS/Swift] 접근 제어(Access Control) Xcode

코드의 세부 구현 내용을 숨기는 것이 가능하도록 만드는 개념 (객체지향의 은닉화가 가능해짐 )

개념

코드의 영역을 분리시켜, 효율적으로 관리가 가능합니다.

class SomeClass {
    private var name = "이름"  // 외부에서 접근불가 하도록 제한 (private 키워드) "은닉화"
    
    func nameChange(name: String) {
        self.name = name
    }
}

let object1 = SomeClass()  

// 인스턴스의 프로퍼티에 접근이 불가합니다.
//object1.name = "홍길동"

// 이름을 속성을 바꾸려면 특정 메서드로 변경은 가능하죠.
object1.nameChange(name: "Danny")
기본 원칙: “타입(Type)” 보다 낮은 수준접근제어사용 불가합니다

사용 불가 예시

open var a: Int = 5  // 여기서 "Int" 타입은 내부적으로 "public"으로 선언

 

스위프트의 접근 수준

모듈(module): 프레임워크, 라이브러리, 앱 등 import 해서 사용할 수 있는 외부의 코드입니다.

모듈

  • open : 다른 모듈에서도 접근가능 / 상속 및 재정의 가능 (제한 낮음)
  • public : 다른 모듈에서도 접근가능 (상속/재정의 불가)
  • internal : 같은 모듈 내에서만 접근가능 (디폴트)
  • fileprivate : 같은 파일 내에서는 어디서나 접근가능
  • private : 해당 구조체나 클래스의 scope 내에서만 접근가능 (제한 높음)

 

특징

이 중 open, public은 프레임워크, 라이브러리, SDK 개발 작업을 할 때 사용하고 보통 internal, fileprivate, private를 사용합니다.

  • open은 클래스의 최고 범위이다.(상속, 재정의를 할 수 있습니다.)
  • public은 구조체의 최고 범위이다.(구조체는 어차피 상속이 없기 때문입니다.)
  • internal은 아무 선언도 하지 않으면 기본적으로 internal level으로 설정됩니다.
  • fileprivate은 같은 파일이라면 어디서나 접근이 가능합니다.
  • private 같은 경우엔 컴파일 시간이 줄어든다 (접근할 수 있는 범위가 가장 적기 때문이죠)
다시 한번 강조하면 “타입(Type)” 보다 낮은 수준의 접근제어는 사용 불가합니다

 

Fileprivate, Private의 차이

말로는 감이 안 잡혔지만, 간단히 코드를 보면서 이해해 봅시다.

같은 파일 내에서는 fileprivate을 사용해도 접근이 가능하지만, 타입이 다르면 같은 파일이라도 private 접근이 불가합니다.

class AType: UIViewController {
    var internalLevel = "Internal Level"
    fileprivate var fileprivateLevel = "Fileprivate Level"
    private var privateLevel = "Private Level"
}

class BType: UIViewController {
    let aType = AType()
    
    func TestAccessLevels() {
    
    	// internal은 같은 모듈에서는 어디든 접근 가능
        aType.internalLevel
        
        // 같은 파일 내부이므로 fileprivate로 접근 가능
        aType.fileprivateLevel
        
        // Error: 'privateLevel' is inaccessible due to 'private' protection level
        aType.privateLevel        
    }
}

 

참고

관습적인 패턴

// 속성(변수)를 선언시 private으로 외부에 감추려는 속성은 _(언더바)를 사용해서 이름 지음
class SomeOtherClass {
    private var _name = "이름"         // 쓰기 - private
    
    var name: String {                // 읽기 - internal
        return _name
    }
}

위와 같이 매번 표현하기가 힘들어서 현재는 업데이트가 된 거 같습니다.

private(set): 저장속성을 외부에서 읽기는 허용하고 쓰기를 제한합니다.

class Hidden {
    private(set) var name = "이름"      // 읽기 - internal / 쓰기 - private
}

// 위와 같은 표현 입니다.

class Hidden {
   internal private(set) var name = "이름"      // 읽기 - internal / 쓰기 - private
}

 

 

부족한 설명이지만, 조금은 이해 가셨나요?

틀린 내용이 있다면 언제든지 지적해 주시면 감사히 받겠습니다. 🫠
읽어주셔서 감사합니다 😃

 

반응형
profile

Danny의 iOS 컨닝페이퍼

@Danny's iOS

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!