[Swift] 프로퍼티와 프로퍼티 감시자

김형근·2024년 7월 21일

[Swift] 문법

목록 보기
11/20

🍎 Swift 프로퍼티와 프로퍼티 감시자 (Property Observers)

  • Swift에서는 프로퍼티를 사용하여 데이터를 저장하고 관리할 수 있습니다. 프로퍼티에는 저장 프로퍼티와 연산 프로퍼티가 있으며, 프로퍼티 값이 변경될 때 특정 동작을 수행할 수 있는 프로퍼티 감시자도 있습니다.

🍏 1. 프로퍼티 (Property)

  • 프로퍼티는 구조체, 클래스, 열거형 내부에 구현할 수 있습니다. 다만 열거형 내부에는 연산 프로퍼티만 구현할 수 있으며, 연산 프로퍼티는 'var' 로만 선언할 수 있습니다.

🧃 1.1 저장 프로퍼티 (Stored Property)

  • 저장 프로퍼티는 변수나 상수로 선언되어 값을 저장합니다.
struct Student {
    // 인스턴스 저장 프로퍼티
    var name: String = ""
    var `class`: String = "Swift"
    var koreanAge: Int = 0

    // 인스턴스 연산 프로퍼티
    // 한국 나이를 기준으로 서양 나이를 계산합니다.
    var westernAge: Int {
        get {
            return koreanAge - 1 // 한국 나이에서 1을 뺀 값을 반환
        }
        set(inputValue) {
            koreanAge = inputValue + 1 // 입력 값을 바탕으로 한국 나이를 설정
        }
    }

    // 타입 저장 프로퍼티
    static var typeDescription: String = "학생" // 모든 학생 인스턴스에 공통적인 설명

    // 읽기 전용 인스턴스 연산 프로퍼티
    var selfIntroduction: String {
        return "저는 \(self.class)\(name)입니다."
    }

    // 읽기 전용 타입 연산 프로퍼티
    static var selfIntroduction: String {
        return "학생타입입니다."
    }
}
  • 저장 프로퍼티는 구조체 또는 클래스의 인스턴스에 저장되는 값을 나타냅니다.
  • 연산 프로퍼티는 실제 값을 저장하지 않고, 대신 다른 프로퍼티나 연산의 결과를 제공합니다.
  • 타입 프로퍼티는 특정 타입에 속하는 프로퍼티로 타입 자체에 속하는 값을 저장합니다.

🧃 1.2 사용 예시

// 타입 연산 프로퍼티 사용
print(Student.selfIntroduction) // 학생타입입니다.

// 인스턴스 생성
var geuni: Student = Student()
geuni.koreanAge = 26

// 인스턴스 저장 프로퍼티 사용
geuni.name = "geuni"
print(geuni.name) // geuni

// 인스턴스 연산 프로퍼티 사용
print(geuni.selfIntroduction) // 저는 Swift반 geuni입니다.

print("제 한국나이는 \(geuni.koreanAge)이고, 미국나이는 \(geuni.westernAge)살 입니다.")
// 제 한국나이는 26살이고, 미국나이는 25살 입니다.
  • 인스턴스 생성 후, 저장 프로퍼티와 연산 프로퍼티를 사용할 수 있습니다.
  • 'selfIntroduction'은 읽기 전용 연산 프로퍼티로 간단한 소개 문장을 반환합니다.

🧃 1.3 응용 예시

struct Money {
    var currencyRate: Double = 1100
    var dollar: Double = 0
    
    // 연산 프로퍼티를 통해 원화를 계산
    var won: Double {
        get {
            return dollar * currencyRate // 달러를 원화로 변환
        }
        set {
            dollar = newValue / currencyRate // 입력된 원화를 달러로 변환하여 저장
        }
    }
}

var moneyInMyPocket = Money()

moneyInMyPocket.won = 11000
print(moneyInMyPocket.won) // 11000

moneyInMyPocket.dollar = 10
print(moneyInMyPocket.won) // 11000
  • 'Money' 구조체는 환율과 달러 금액을 저장하는 프로퍼티와 원화를 계산하는 연산 프로퍼티를 가지고 있습니다.
  • 'won' 프로퍼티를 통해 원화 값을 설정하고 계산할 수 있습니다.

🍏 2. 프로퍼티 감시자 (Property Observers)

  • 프로퍼티 감시자를 사용하면 프로퍼티 값이 변경될 떄 원하는 동작을 수행할 수 있습니다.

🧃 2.1 정의와 사용 예시

struct Money {
    // 프로퍼티 감시자 사용
    var currencyRate: Double = 1100 {
        // 새로운 값이 설정되기 직전에 호출
        willSet(newRate) {
            print("환율이 \(currencyRate)에서 \(newRate)으로 변경될 예정입니다.")
        }
        // 새로운 값이 설정된 직후에 호출
        didSet(oldRate) {
            print("환율이 \(oldRate)에서 \(currencyRate)으로 변경되었습니다.")
        }
    }
    
    // 프로퍼티 감시자 사용
    var dollar: Double = 0 {
        // willSet의 암시적 매개변수 이름 newValue
        willSet {
            print("\(dollar)달러에서 \(newValue)달러로 변경될 예정입니다.")
        }
        
        // didSet의 암시적 매개변수 이름 oldValue
        didSet {
            print("\(oldValue)달러에서 \(dollar)달러로 변경되었습니다.")
        }
    }
    
    // 연산 프로퍼티
    var won: Double {
        get {
            return dollar * currencyRate // 달러를 원화로 변환
        }
        set {
            dollar = newValue / currencyRate // 입력된 원화를 달러로 변환하여 저장
        }
        
        // 프로퍼티 감시자와 연산 프로퍼티 기능을 동시에 사용할 수 없습니다.
        // willSet {
        //
        // }
    }
}

// 사용 예시
var moneyInMyPocket: Money = Money()

// 환율이 1100.0에서 1150.0으로 변경될 예정입니다.
moneyInMyPocket.currencyRate = 1150
// 환율이 1100.0에서 1150.0으로 변경되었습니다.

// 0.0달러에서 10.0달러로 변경될 예정입니다.
moneyInMyPocket.dollar = 10
// 0.0달러에서 10.0달러로 변경되었습니다.

print(moneyInMyPocket.won) // 11500.0
  • 'willSet'과 'didSet'을 사용하여 프로퍼티 값이 변경되기 전과 후에 특정 동작을 수행할 수 있습니다.
  • 'newValue' 와 'oldValue' 는 각각 변경될 값과 이전 값을 나타냅니다.

🧃 2.3 지역변수, 전역변수에서의 사용

  • 프로퍼티 감시자의 기능은 함수, 메서드, 클로저, 타입 등의 외부에 위치한 지역/전역 변수에도 모두 사용 가능합니다.
var a: Int = 100 {
    willSet {
        print("\(a)에서 \(newValue)로 변경될 예정입니다.")
    }
    didSet {
        print("\(oldValue)에서 \(a)로 변경되었습니다.")
    }
}

// 100에서 200로 변경될 예정입니다.
a = 200
// 100에서 200으로 변경되었습니다.

지역변수나 전역변수에서도 'willSet' 과 'didSet' 을 사용하여 값이 변경될 떄의 동작을 정의할 수 있습니다.

profile
꾸준히 기록하기

0개의 댓글