[Swift 정면돌파] 09. 프로퍼티

H43RO·2021년 8월 4일
2

Swift 정면돌파

목록 보기
9/19
post-thumbnail

오늘은 스위프트에 존재하는 프로퍼티의 종류와 각각의 용법, 그리고 프로퍼티 감시자의 개념에 대하여 알아보았다.

프로퍼티

프로퍼티는 구조체, 열거형 그리고 클래스와 관련한 어떠한 값을 담는 공간

크게 저장 프로퍼티, 연산 프로퍼티로 나눌 수 있음
저장 프로퍼티 : 말 그대로 값을 저장하고 있는 프로퍼티
연산 프로퍼티 : 특정 연산 수행 결과를 반환하는 프로퍼티

프로퍼티의 종류

  1. 인스턴스 저장 프로퍼티
  2. 타입 저장 프로퍼티
  3. 인스턴스 연산 프로퍼티
  4. 타입 연산 프로퍼티
  5. 지연 저장 프로퍼티

프로퍼티 정의와 사용

  • 프로퍼티는 구조체, 클래스, 열거형 내부에 구현할 수 있음

  • 다만 열거형 내부에는 연산 프로퍼티만 구현할 수 있음

  • 연산 프로퍼티는 항상 var 로만 선언할 수 있음

  • 연산 프로퍼티를 읽기 전용으로 구현할 수 있지만, 쓰기 전용으로는 구현할 수 없음

  • 읽기 전용으로 구현하려면 get 블록만 작성해주면 됨
    (읽기 전용은 set 생략 가능)

  • 읽기, 쓰기 모두 가능하게 하려면 get, set 블록 모두 구현해주면 됨

  • set 블록에서 암시적 매개변수 newValue 를 사용할 수 있음

struct Student {
    
    // 인스턴스 저장 프로퍼티
    var name: String = ""
		// 이전에 배웠던대로, 기본 키워드 사용시 `` 로 감싸주면 됨
    var `class`: String = "Swift"
    var koreanAge: Int = 0
    
    // 인스턴스 연산 프로퍼티
    var westernAge: Int {
        get {
            return koreanAge - 1
        }
        set(inputValue) {
            koreanAge = inputValue + 1
        }
    }
    
    // 타입 저장 프로퍼티
    static var typeDescription: String = "학생"
    
    /*
    // 일반적인 인스턴스 메소드 
    func selfIntroduce() {
        print("저는 \(self.class)반 \(name)입니다")
    }
     */
    
    // 읽기전용 인스턴스 연산 프로퍼티
    // 위 selfIntroduce() 메소드 대체 가능
    var selfIntroduction: String {
        get {
            return "저는 \(self.class)\(name)입니다"
        }
    }
        
    /*
     // 타입 메소드
     static func selfIntroduce() {
	     print("학생타입입니다")
     }
     */
    
    // 읽기전용 타입 연산 프로퍼티
    // 읽기전용에서는 get 생략 가능
    static var selfIntroduction: String {
        return "학생타입입니다"
    }
}

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

// 인스턴스 생성
var yagom: Student = Student()
yagom.koreanAge = 10

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

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

print("제 한국나이는 \(yagom.koreanAge)살이고, 미국 나이는 \(yagom.westernAge)살입니다.")
// "제 한국나이는 10살이고, 미국 나이는 9살입니다."

프로퍼티 응용

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

지역변수 및 전역변수

→ 저장 프로퍼티와 연산 프로퍼티의 기능은 함수, 메소드, 클로저, 타입 등의 외부에
위치한 지역 / 전역 변수에도 모두 사용 가능

var a: Int = 100
var b: Int = 200
var sum: Int {
    return a + b
}

print(sum) // 300

프로퍼티 감시자

프로퍼티 감시자 개념

  • 프로퍼티의 값이 변경될 때 원하는 특정 동작을 수행할 수 있음

  • 값이 변경되기 직전에 willSet이, 값이 변경된 직후에 `didSet'이 호출됨

    • 둘 중 필요한 하나만 구현해 주어도 무관함
  • 변경되는 값이 기존 값과 똑같더라도 프로퍼티 감시자는 항상 동작함

  • willSet 블럭에서는 암시적 매개변수 newValuedidSet 블럭에서는 oldValue사용할 수 있음

  • 프로퍼티 감시자는 연산 프로퍼티에는 사용할 수 없음

  • 프로퍼티 감시자는 함수, 메소드, 클로저, 타입 등의 지역/전역 변수에 모두 사용 가능

정의 및 사용

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
profile
어려울수록 기본에 미치고 열광하라

0개의 댓글