[iOS 사전캠프] 프로퍼티 옵저버, 접근 제한자

DoyleHWorks·2024년 10월 15일
1

프로퍼티 옵저버

var 변수명: 타입 {
    willSet(새로운값) {
        // 새로운 값이 저장되기 직전에 실행할 코드
    }
    didSet {
        // 새로운 값이 저장된 후에 실행할 코드
    }
}
  • willSet: 프로퍼티를 관찰(observe)하다가 새 값이 저장되기 직전에 실행되며,
    기본적으로 newValue라는 이름으로 새로운 값에 접근할 수 있다.
  • didSet: 프로퍼티를 관찰(observe)하다가 새 값이 저장된 직후에 실행되며,
    기본적으로 oldValue라는 이름으로 이전 값에 접근할 수 있다.
  • 프로퍼티 옵저버의 동작 방식
    • 초기화 시에는 호출되지 않음: 프로퍼티 옵저버는 값이 변경될 때만 호출됨
    • willSetnewValue, didSetoldValue는 각각 직접 정의할 수도 있음
  • 프로퍼티 옵저버의 사용 시점
    • 프로퍼티 옵저버는 저장 프로퍼티에서만 직접적으로 사용할 수 있다.
    • 연산 프로퍼티의 경우 값이 설정될 때 자동으로 getter/setter가 호출되므로, 프로퍼티 옵저버를 사용할 수 없다
    • 애초에 연산 프로퍼티에서는 willSet, didSet이 필요 없을 때가 많다.

예시

var myProperty: Int = 20{
   didSet(oldValue){
      print(oldValue) 
   }
   willSet(newValue){
      print(newValue) 
   }
}

var name: String = "Unknown" {
    willSet {
        print("현재 이름 = \(name), 바뀔 이름 = \(newValue)")
    }
    didSet {
        print("현재 이름 = \(name), 바뀌기 전 이름 = \(oldValue)")
    }
}
 
name = "Peter"
// willSet이 먼저 실행
// 현재 이름 = Unknown, 바뀔 이름 = Peter
// 현재 이름 = Peter, 바뀌기 전 이름 = Unknown

접근 제한자

접근 제한자(Access Control)는 Swift에서 클래스, 구조체, 열거형, 프로토콜, 그리고 그 안의 프로퍼티 및 메소드의 접근 권한을 정의하는 방법이다. 데이터 은닉과 모듈화를 강화하고, 코드의 유지보수성을 높일 수 있다.

  • [제약이 적음] open < public < internal < fileprivate < private [제약이 많음]
  1. open
  • 가장 느슨한 접근 제한자
  • 다른 모듈에서 이 클래스를 상속할 수 있고, 모듈 외부에서도 사용 가능하다.
  • 주로 프레임워크를 설계할 때 사용된다.
// 다른 모듈에서도 사용 가능
open class Animal {
    open func makeSound() {
        print("Animal sound")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Bark")
    }
}
  1. public
  • 모듈 외부에서 사용 가능하지만, 상속은 불가능하다.
  • 클래스와 메소드는 public으로 설정할 수 있다.
    public 메소드는 해당 클래스를 상속하더라도 (위의 Dog 클래스처럼은) 오버라이드할 수 없다.
public class Cat {
    public func meow() {
        print("Meow")
    }
}
  1. internal
  • 기본 접근 제한자이다. 아무 접근 제한자도 명시하지 않을 경우 기본적으로 internal로 설정된다.
  • 같은 모듈 내에서만 접근이 가능하고 모듈 외부에서는 사용할 수 없다.
class Fish {
    func swim() {
        print("Swim")
    }
}
  1. private
  • 가장 제한적인 접근 제한자
  • 정의된 블록(클래스, 구조체, 익스텐션) 내에서만 접근할 수 있다.
  • 같은 클래스나 구조체 내에서만 접근할 수 있고, 하위 클래스에서는 접근할 수 없다.
class Car {
    private var engine: String = "V8"
    
    private func startEngine() {
        print("Engine started")
    }
    
    func drive() {
        startEngine() // 접근 가능
    }
}

let myCar = Car()
// myCar.engine // 오류: 'engine'은 private이므로 접근 불가
// myCar.startEngine() // 오류: 'startEngine'은 private이므로 접근 불가

문제 풀이는 다음 글에서

profile
Reciprocity lies in knowing enough

0개의 댓글