λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

🍎 iOS/Swift

[Swift] ν”„λ‘œνΌν‹°(Properties) - ν”„λ‘œνΌν‹° μ˜΅μ €λ²„

μ•ˆλ…•ν•˜μ„Έμš” μ œμΈμž…λ‹ˆλ‹€!

μ§€λ‚œ κ²Œμ‹œκΈ€μ— 이어 ν”„λ‘œνΌν‹° 2탄(lazyκΉŒμ§€ ν•©μΉ˜λ©΄ 3탄..)으둜 ν”„λ‘œνΌν‹° μ˜΅μ €λ²„μ— λŒ€ν•΄μ„œ 정리해보렀고 ν•©λ‹ˆλ‹€.

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λŠ” UI μ—…λ°μ΄νŠΈκ°€ ν•„μš”ν•  λ•Œ μœ μš©ν•˜κ²Œ 많이 μ‚¬μš©ν•˜κ²Œ λ˜λŠ” 것 κ°™μ•„μ„œ(λ¬Όλ‘  Rx둜 λΉ„λ™κΈ°μ μœΌλ‘œ μ—…λ°μ΄νŠΈ λ˜λ„λ‘ μ²˜λ¦¬ν•΄μ€„ μˆ˜λ„ μžˆκ² μ§€λ§Œ..) 잘 정리해두면 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€!!

 

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œλŠ” μ €μž₯ ν”„λ‘œνΌν‹°, μ—°μ‚° ν”„λ‘œνΌν‹°μ— λŒ€ν•œ 이해가 ν•„μš”ν•˜λ‹ˆ κ°œλ…μ΄ 잘 μ•ˆμž‘ν˜€μžˆλ‹€λ©΄ μ•„λž˜ κ²Œμ‹œκΈ€λ“€μ„ 읽고 μ˜€μ‹œλŠ” 것을 μΆ”μ²œλ“œλ¦½λ‹ˆλ‹€~!

 

1) μ €μž₯ ν”„λ‘œνΌν‹°(Stored Properties)와 μ—°μ‚° ν”„λ‘œνΌν‹°(Computed Properties)

2) 지연 μ €μž₯ ν”„λ‘œνΌν‹°(Lazy Stored Properties)

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„ (Property Observers)

ν”„λ‘œνΌν‹°μ—λŠ” μƒˆ 값이 μ„€μ •(set) 될 λ•Œλ§ˆλ‹€ 이 이벀트λ₯Ό 감지할 수 μžˆλŠ” ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λŠ” ν”„λ‘œνΌν‹°μ˜ 값이 μƒˆλ‘œ 할당될 λ•Œλ§ˆλ‹€ 호좜되기 λ•Œλ¬Έμ— ν”„λ‘œνΌν‹°μ˜ 값이 변경됨에 따라 μ μ ˆν•œ μž‘μ—…μ„ μ·¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 λ•Œ, λ³€κ²½λ˜λŠ” 값이 ν˜„μž¬μ˜ κ°’κ³Ό λ™μΌν•˜λ”λΌλ„ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

지연(lazy) μ €μž₯ ν”„λ‘œνΌν‹°λ₯Ό μ œμ™Έν•˜κ³ , μ •μ˜λœ μ €μž₯ ν”„λ‘œνΌν‹°μ— ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ, ν”„λ‘œνΌν‹° μž¬μ •μ˜(override)λ₯Ό 톡해 상속받은 ν”„λ‘œνΌν‹°(μ €μž₯ ν”„λ‘œνΌν‹°, μ—°μ‚° ν”„λ‘œνΌν‹° λ‘˜ λ‹€ κ°€λŠ₯)에도 ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 상속받지 μ•Šμ€ μ—°μ‚° ν”„λ‘œνΌν‹°μ—λŠ” ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μœΌλ©° ν•  μˆ˜λ„ μ—†μŠ΅λ‹ˆλ‹€. μ—°μ‚° ν”„λ‘œνΌν‹°λŠ” setterμ—μ„œ κ°’μ˜ λ³€ν™”λ₯Ό 감지 ν•  수 있기 λ•Œλ¬Έμ΄μ£ ! κ·Έλž˜μ„œ λ”°λ‘œ μ˜΅μ €λ²„λ₯Ό μ •μ˜ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•  수 μžˆλŠ” ν”„λ‘œνΌν‹°
1. μ €μž₯ ν”„λ‘œνΌν‹° (lazy μ œμ™Έ)
2. 상속받은 μ €μž₯, μ—°μ‚° ν”„λ‘œνΌν‹°

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„ λ©”μ„œλ“œ

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„μ—λŠ” ν”„λ‘œνΌν‹°μ˜ 값이 λ³€κ²½λ˜κΈ° 직전에 ν˜ΈμΆœλ˜λŠ” willSet λ©”μ„œλ“œμ™€ 값이 λ³€κ²½λœ 직후에 ν˜ΈμΆœλ˜λŠ” didSet λ©”μ„œλ“œ μ΄λ ‡κ²Œ 두 가지가 μžˆμŠ΅λ‹ˆλ‹€. ν•˜λ‚˜μ˜ ν”„λ‘œνΌν‹°μ— λŒ€ν•΄ ν•˜λ‚˜ λ˜λŠ” 두 가지 λ©”μ„œλ“œ λͺ¨λ‘ μ •μ˜ ν•  수 μžˆμŠ΅λ‹ˆλ‹€!

willSet λ©”μ„œλ“œμ—μ„œλŠ” μƒˆ κ°’μ˜ νŒŒλΌλ―Έν„°λͺ…을, didSetμ—μ„œλŠ” λ³€κ²½λ˜κΈ° μ „ κ°’μ˜ νŒŒλΌλ―Έν„°λͺ…을 지정할 수 μžˆλŠ”λ°, λ§€κ°œλ³€μˆ˜λͺ…을 λ”°λ‘œ μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ κΈ°λ³Έ κ°’μœΌλ‘œ willSet λ©”μ„œλ“œμ—λŠ” newValueκ°€, didSet λ©”μ„œλ“œμ—λŠ” oldValue λΌλŠ” 이름이 μžλ™ μ§€μ •λ©λ‹ˆλ‹€.

- willSet: 값이 μ €μž₯되기 λ°”λ‘œ 직전에 호좜 됨 (κΈ°λ³Έ λ§€κ°œλ³€μˆ˜λͺ…: newValue)
- didSet: μƒˆ 값이 μ €μž₯되고 λ‚œ 직후에 호좜 됨 (κΈ°λ³Έ λ§€κ°œλ³€μˆ˜λͺ…: oldValue)

 

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό 예제 μ½”λ“œλ‘œ μ‚΄νŽ΄λ΄…μ‹œλ‹€!

 

class Account {
    var credit: Int = 0 { // μ €μž₯ ν”„λ‘œνΌν‹°
        willSet {
            print("μž”μ•‘μ΄ \(credit)μ›μ—μ„œ \(newValue)μ›μœΌλ‘œ 변경될 μ˜ˆμ •μž…λ‹ˆλ‹€.")
            print(newValue)
        }
        
        didSet {
            print("μž”μ•‘μ΄ \(oldValue)μ›μ—μ„œ \(credit)μ›μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
            print(oldValue)
        }
    }
}

let myAccount: Account = Account()

// Print: μž”μ•‘μ΄ 0μ›μ—μ„œ 1000μ›μœΌλ‘œ 변경될 μ˜ˆμ •μž…λ‹ˆλ‹€.
// Print: 1000
myAccount.credit = 1000
// Print: μž”μ•‘μ΄ 0μ›μ—μ„œ 1000μ›μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
// Print: 0

 

μœ„μ˜ μ½”λ“œλŠ” myAccountλΌλŠ” μ΄λ¦„μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , ν•΄λ‹Ή μΈμŠ€ν„΄μŠ€μ˜ credit이 λΌλŠ” μ €μž₯ ν”„λ‘œνΌν‹°μ˜ 값을 1000으둜 λ³€κ²½ν•΄μ£ΌλŠ” μ˜ˆμ œμž…λ‹ˆλ‹€. willSetκ³Ό didSet λ©”μ„œλ“œ λͺ¨λ‘ μΆ”κ°€ν•΄μ£Όμ—ˆκΈ° λ•Œλ¬Έμ— credit의 값이 λ°”λ€ŒκΈ° 직전, 직후에 각 λ©”μ„œλ“œμ—μ„œ μ„€μ •ν•œ ν”„λ¦°νŠΈλ¬Έμ΄ 좜λ ₯λ˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€!

 

μ—¬κΈ°μ„œ ν•œ 가지 μ£Όμ˜ν•  점은, willSet의 λ§€κ°œλ³€μˆ˜ newValueλŠ” λ³€κ²½'될' 값을 전달받고, didSet의 λ§€κ°œλ³€μˆ˜ oldValueλŠ” λ³€κ²½λ˜κΈ° 'μ „' 값을 μ „λ‹¬λ°›λŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€! λ¬Όλ‘  κΈ°λ³Έ λ§€κ°œλ³€μˆ˜ 이름이 μ§κ΄€μ μ΄μ–΄μ„œ λ°”λ‘œ 이해할 수 μžˆκ² μ§€λ§Œ, didSet의 경우 값이 λ³€κ²½λœ 후에 호좜되기 λ•Œλ¬Έμ— λ§€κ°œλ³€μˆ˜κ°€ λ³€κ²½λœ 값을 λ‹΄κ³ μžˆμ„ κ²ƒλ§Œ 같은 λŠλ‚Œμ΄κΈ° λ•Œλ¬Έμ—(?) ν•œ 번 짚고 λ„˜μ–΄κ°€λ©΄ 쒋을 것 κ°™μ•„μš”! μœ„μ—μ„œλ„ 확인할 수 μžˆλ“―μ΄ credit의 값은 이미 1000으둜 λ³€κ²½λ˜μ—ˆμ§€λ§Œ ν”„λ¦°νŠΈ λ˜λŠ” 값은 μ΄μ „μ˜ 값인 0μ΄λΌλŠ” 점!! 

 

class Account {
    var credit: Int = 0 { // μ €μž₯ ν”„λ‘œνΌν‹°
        willSet {
            print("μž”μ•‘μ΄ \(credit)μ›μ—μ„œ \(newValue)μ›μœΌλ‘œ 변경될 μ˜ˆμ •μž…λ‹ˆλ‹€.")
        }
        
        didSet {
            print("μž”μ•‘μ΄ \(oldValue)μ›μ—μ„œ \(credit)μ›μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.")
        }
    }
    
    var dollarValue: Double { // μ—°μ‚° ν”„λ‘œνΌν‹°
        get {
            return Double(credit) / 1000.0
        }
        
        set {
            credit = Int(newValue * 1000)
            print("μž”μ•‘μ„ \(newValue)λ‹¬λŸ¬λ‘œ λ³€κ²½ 쀑!!")
        }
    }
}

class ForeignAccount: Account {
    override var dollarValue: Double { // μ—°μ‚° ν”„λ‘œνΌν‹° μž¬μ •μ˜
        willSet {
            print("μž”μ•‘μ΄ \(dollarValue)λ‹¬λŸ¬μ—μ„œ \(newValue)둜 변경될 μ˜ˆμ •")
        }
        
        didSet {
            print("μž”μ•‘μ΄ \(oldValue)λ‹¬λŸ¬μ—μ„œ \(dollarValue)둜 변경됨")
        }
    }
}

let myAccount: ForeignAccount = ForeignAccount()

// Print1: μž”μ•‘μ΄ 0μ›μ—μ„œ 1000μ›μœΌλ‘œ 변경될 μ˜ˆμ •μž…λ‹ˆλ‹€.
myAccount.credit = 1000
// Print2: μž”μ•‘μ΄ 0μ›μ—μ„œ 1000μ›μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

// Print3: μž”μ•‘μ΄ 1.0λ‹¬λŸ¬μ—μ„œ 2.0둜 변경될 μ˜ˆμ •
// Print4: μž”μ•‘μ΄ 1000μ›μ—μ„œ 2000μ›μœΌλ‘œ 변경될 μ˜ˆμ •μž…λ‹ˆλ‹€.
// Print5: μž”μ•‘μ΄ 1000μ›μ—μ„œ 2000μ›μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
myAccount.dollarValue = 2  // Print6: μž”μ•‘μ„ 2.0λ‹¬λŸ¬λ‘œ λ³€κ²½ 쀑!!
// Print7: μž”μ•‘μ΄ 1.0λ‹¬λŸ¬μ—μ„œ 2.0둜 변경됨

print(myAccount.credit) // 2000

 

μ•žμ„œ 봀던 μ½”λ“œμ— μ—°μ‚° ν”„λ‘œνΌν‹°μ™€ κ΄€λ ¨ν•œ μ½”λ“œλ₯Ό μΆ”κ°€ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€!

Account ν΄λž˜μŠ€μ— μ ‘κ·Όμž, μ„€μ •μžκ°€ λͺ¨λ‘ κ΅¬ν˜„λœ dollarValueλΌλŠ” μ—°μ‚° ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•˜κ³ , Accoutλ₯Ό 상속 λ°›λŠ” μžμ‹ 클래슀인 ForeignAccountλΌλŠ” ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή μ—°μ‚° ν”„λ‘œνΌν‹°λ₯Ό overrideν•˜μ—¬ ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•΄μ£Όμ—ˆμŠ΅λ‹ˆλ‹€.

 

ν”„λ¦°νŠΈλ¬Έμ„ 잘 보면 μ–Έμ œ μ–΄λ–€ λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λŠ”μ§€ νŒŒμ•…ν•  수 μžˆμ„ 것 κ°™μ€λ°μš”! λ¨Όμ €, ν”„λ¦°νŠΈ 1, 2λ²ˆμ€ λΆ€λͺ¨ 클래슀의 μ €μž₯ ν”„λ‘œνΌν‹° κ°’(credit)을 λ°”κΏ€ λ•Œ κ°’ λ³€κ²½ 직전, 직후에 willSet, didSet이 각각 ν˜ΈμΆœλ˜μ–΄ ν”„λ¦°νŠΈλœ κ²ƒμž…λ‹ˆλ‹€.

이제 ν”„λ¦°νŠΈ3~7λ²ˆμ„ μ‚΄νŽ΄λ΄…μ‹œλ‹€. μ—°μ‚° ν”„λ‘œνΌν‹°μΈ dollarValue에 μƒˆλ‘œμš΄ 값인 2λ₯Ό μ„ΈνŒ…ν•˜λ©΄, set λ©”μ„œλ“œκ°€ 호좜(ν”„λ¦°νŠΈ6)될 κ²ƒμž…λ‹ˆλ‹€!

그리고, μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λ₯Ό 톡해 ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λ₯Ό μΆ”κ°€ν•΄μ£Όμ—ˆκΈ° λ•Œλ¬Έμ— 2λΌλŠ” μƒˆλ‘œμš΄ 값을 μ„ΈνŒ…ν•˜κΈ° 직전, 직후에 μ˜΅μ €λ²„ λ©”μ„œλ“œκ°€ 호좜될 κ²ƒμž…λ‹ˆλ‹€! λ˜ν•œ, μ—°μ‚° ν”„λ‘œνΌν‹°μ˜ set λ©”μ„œλ“œ μ•ˆμ—μ„œ creditμ΄λΌλŠ” μ €μž₯ ν”„λ‘œνΌν‹°μ˜ 값을 λ³€κ²½ν•΄μ£Όκ³  있기 λ•Œλ¬Έμ— credit의 μ˜΅μ €λ²„ λ©”μ„œλ“œλ“€λ„ ν•¨κ»˜ ν˜ΈμΆœλ©λ‹ˆλ‹€!! myAccount의 credit을 ν”„λ¦°νŠΈλ¬Έμ„ 톡해 확인해보면 setterμ—μ„œ μ—°μ‚°ν•œ 결과인 2000이 μ°νžˆλŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ „μ—­λ³€μˆ˜μ™€ μ§€μ—­λ³€μˆ˜

ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λŠ” μ§€μ—­λ³€μˆ˜ 뿐만 μ•„λ‹ˆλΌ μ „μ—­λ³€μˆ˜μ—λ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. (μ—°μ‚° ν”„λ‘œνΌν‹° κΈ°λŠ₯도 κ°€λŠ₯)

μœ„μ—μ„œ μ‚΄νŽ΄λ³Έ μ˜ˆμ œλ“€μ€ λͺ¨λ‘ 클래슀 μ•ˆμ—μ„œ μ„ μ–Έλœ μ§€μ—­λ³€μˆ˜λ“€μ΄μ—ˆλŠ”λ°μš”, ν•¨μˆ˜λ‚˜ λ©”μ„œλ“œ, ν΄λ‘œμ €, 클래슀, ꡬ쑰체, μ—΄κ±°ν˜• λ“±μ˜ λ²”μœ„ λ°–μ—μ„œ μ„ μ–Έν•˜λŠ” λ³€μˆ˜λ“€μ—λ„ λͺ¨λ‘ ν”„λ‘œνΌν‹° μ˜΅μ €λ²„ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€!

μ°Έκ³ 
- μ „μ—­λ³€μˆ˜: ν•¨μˆ˜, λ©”μ†Œλ“œ, ν΄λ‘œμ € λ˜λŠ” type context 외뢀에 μ •μ˜λ˜λŠ” λ³€μˆ˜

- μ§€μ—­λ³€μˆ˜: ν•¨μˆ˜, λ©”μ†Œλ“œ λ˜λŠ” closure context λ‚΄μ—μ„œ μ •μ˜λ˜λŠ” λ³€μˆ˜

 

μ „μ—­λ³€μˆ˜ λ˜λŠ” μ „μ—­ μƒμˆ˜λŠ” 지연 μ €μž₯ ν”„λ‘œνΌν‹°μ²˜λŸΌ 처음 μ ‘κ·Όν•  λ•Œ 졜초둜 연산이 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— lazy ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 연산을 늦좜 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. λ°˜λŒ€λ‘œ μ§€μ—­λ³€μˆ˜ 및 지역 μƒμˆ˜λŠ” μ ˆλŒ€λ‘œ 지연 μ—°μ‚°λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ‹€μ œλ‘œ μ‚¬μš©λ  λ•Œ μ΄ˆκΈ°ν™”ν•˜κ³  μ‹Άλ‹€λ©΄ lazy ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€! 

 


[참고 자료]

 

ν”„λ‘œνΌν‹° (Properties) - The Swift Language Guide (ν•œκ΅­μ–΄)

ν”„λ‘œνΌν‹°λŠ” 클래슀, ꡬ쑰체, μ—΄κ±°ν˜•κ³Ό κ΄€λ ¨ν•œ κ°’μž…λ‹ˆλ‹€. ν”„λ‘œνΌν‹°μ˜ μ’…λ₯˜μ—λŠ” μ €μž₯ ν”„λ‘œνΌν‹°(Stored Properties)와 κ³„μ‚°λœ ν”„λ‘œνΌν‹°(Computed Properties)κ°€ μžˆμŠ΅λ‹ˆλ‹€. μ €μž₯ ν”„λ‘œνΌν‹°λŠ” 말 κ·ΈλŒ€λ‘œ 값을 μ €

jusung.gitbook.io

 

μŠ€μœ„ν”„νŠΈ ν”„λ‘œκ·Έλž˜λ°: Swift 5 | μ•Όκ³° - ꡐ보문고

μŠ€μœ„ν”„νŠΈ ν”„λ‘œκ·Έλž˜λ°: Swift 5 | 문법을 λ„˜μ–΄ ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„λ„ μ΅νžˆλŠ” μŠ€μœ„ν”„νŠΈ 5μŠ€μœ„ν”„νŠΈ 5의 핡심 ν‚€μ›Œλ“œλŠ” ‘μ•ˆμ •ν™”’λ‹€. ABI μ•ˆμ •ν™” 덕뢄에 버전과 ν™˜κ²½μ— 크게 영ν–₯받지 μ•Šκ³  더 μœ μ—°ν•˜

product.kyobobook.co.kr

 

Swift ) Properties - Property Observers(ν”„λ‘œνΌν‹° μ˜΅μ €λ²„)

μ•ˆλ…•ν•˜μ„Έμš” :) Zeddμž…λ‹ˆλ‹€. μ˜€λŠ˜μ€ μ €λ²ˆ 글에 μ΄μ–΄μ„œ ν”„λ‘œνΌν‹° μ˜΅μ €λ²„λΌλŠ” 것을 λ³Όκ±°μ—μš” :)이 글을 λ³΄μ‹œκΈ°μ „μ—: < Properties - Stored Property(μ €μž₯ ν”„λ‘œνΌν‹°) μ½μœΌλŸ¬κ°€κΈ° > : μœ„ 두 글을 κΌ­!! 읽고와주세

zeddios.tistory.com