Skip to content

Latest commit

Β 

History

History
145 lines (99 loc) Β· 6.95 KB

KVO.md

File metadata and controls

145 lines (99 loc) Β· 6.95 KB

KVO (key-value-observing)

Observing μ–΄λ””μ„œ 많이 λ³Έκ±° 같은데…

RxSwiftλ₯Ό κ³΅λΆ€ν•˜μ‹  뢄이라면 ObservableλΌλŠ” 단어가 μ΅μˆ™ν•  것 κ°™μŠ΅λ‹ˆλ‹€.

Observable도 κ°μ‹œμžλΌλŠ” λœ»μ„ 가지고 있고 Observing은 κ°μ‹œν•œλ‹€λŠ” λœ»μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. 그러면 μ§€κΈˆλΆ€ν„° KVOλŠ” μ–΄λ–€ 것을 κ°μ‹œν•˜λŠ”μ§€ μ•Œμ•„λ³΄λ„λ‘ ν• κΉŒμš”?

κ²°λ‘ λΆ€ν„° λ§μ”€λ“œλ¦¬μžλ©΄ KVOλŠ” λ‹€λ₯Έ 였브젝트의 속성을 κ°μ‹œν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.

아직 잘 와 닿지 μ•ŠλŠ”λ°μš©β€¦

μ•„λž˜ 더 μžμ„Έν•œ μ„€λͺ…을 ν•΄λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.

  • νŠΉμ • ν‚€ κ°’μ˜ λ³€ν™”λ₯Ό 감지기 μœ„ν•œ κΈ°λŠ₯
  • 객체의 ν”„λ‘œνΌν‹° λ³€κ²½ 사항을 λ‹€λ₯Έ 객체에 μ•Œλ¦¬κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” μ½”μ½”μ•„ ν”„λ‘œκ·Έλž˜λ° νŒ¨ν„΄
  • Modelκ³Ό View 같이 λ…Όλ¦¬μ μœΌλ‘œ λΆ„λ¦¬λœ νŒŒνŠΈκ°„μ˜ λ³€κ²½ 사항을 μ „λ‹¬ν•˜λŠ”λ° μœ μš©ν•˜λ‹€
  • KVOλŠ” λͺ¨λΈ λ ˆμ΄μ–΄μ™€ λ·° λ ˆμ΄μ–΄ 같이 λ…Όλ¦¬μ μœΌλ‘œ λΆ„λ¦¬λ˜μ–΄ μžˆλŠ” 였브젝트 κ°„ 메세지λ₯Ό 전달 ν•©λ‹ˆλ‹€.
  • νƒ€μž… μ •μ˜ μ™ΈλΆ€μ—μ„œ obseverλ₯Ό μΆ”κ°€ν•  λ•Œ μ‚¬μš©ν•œλ‹€.

μ‹œκ°ν™”

KVOλ₯Ό μ‹œκ°ν™” ν•΄λ³Όκ²Œμš”.

κ°’ λ³€κ²½ -> κ°μ‹œν•˜κ³  μžˆλŠ” 였브젝트 ν—¨λ“€λŸ¬κ°€ 호좜됨 -> handler μž‘λ™

μœ„ λ™μž‘μ΄ 생각보닀 어렡지 μ•Šμ£ ??

이제 본격적 μ„€λͺ…γ…‡γ…‘…

μ•„! λ§žλ‹€ KVO λ₯Ό μ•ŒκΈ° μœ„ν•΄μ„œ 사전에 μ•Œκ³  κ°€μ•Όν•˜λŠ” 지식이 μžˆμŠ΅λ‹ˆλ‹€.

μ•Œκ³  κ°€μ•Όν•  것

KVOλ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” NSOjectλ₯Ό μƒμ†ν•΄μ•Όν•©λ‹ˆλ‹€. 상속을 λ°›μ•„μ•Όν•˜κΈ° λ•Œλ¬Έμ—, Classμ—μ„œλ§Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜κ³ μš”. observe ν•˜λ €λŠ” ν”„λ‘œνΌν‹°μ— @objc attribute와 dynamic modifierλ₯Ό λΆ™μ—¬μ£Όμ–΄μ•Όν•©λ‹ˆλ‹€.

μ΄λ•Œ Dynamic modifier이 μ„ μ–Έλœ 뢀뢄에 ν•œν•΄ Objc λŸ°νƒ€μž„ 방식을 μ‚¬μš©ν•˜κ² λ‹€λŠ” 것이고, λŸ°νƒ€μž„ μ‹œμ μ— ν˜ΈμΆœν•΄μ•Ό ν•  νŠΉμ • λ©”μ†Œλ“œμ˜ κ΅¬ν˜„μ„ κ²°μ •ν•˜λŠ” 것이닀.

κ°μ‹œμžλ₯Ό μ •μ˜ν•˜λŠ” 방법

κ°μ‹œμž 역할을 ν•˜λŠ” μΈμŠ€ν„΄μŠ€λŠ” ν•œ 개 μ΄μƒμ˜ 속성을 κ°μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ°μ‹œμžμ˜ μΈμŠ€ν„°μŠ€λŠ” observe(_:options:changeHandler:) λ©”μ†Œλ“œμ— κ°μ‹œλ₯Ό μ›ν•˜λŠ” μ†μ„±μ˜ key-pathλ₯Ό μ „λ‹¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. ν˜ΈμΆœν•˜λŠ” μ‹œμ λΆ€ν„° μ†μ„±μ˜ κ°’ 변경을 κ°μ‹œν•©λ‹ˆλ‹€.

  1. νŒŒλΌλ―Έν„°μ—λŠ” \.objectToObserveλŠ” objectToObserve μΈμŠ€ν„΄μŠ€μ˜ 속은 key pathμž…λ‹ˆλ‹€.
  2. νŒŒλΌλ―Έν„°μΈ [.old, .new]λŠ” λ§ˆμ§€λ§‰ 트레일링 ν΄λ‘œμ €μ— oldValue와 newValue λΌλŠ” 속성을 μ‚¬μš©μ—¬λΆ€ 결정을 ν•΄μ•Όν•©λ‹ˆλ‹€.
    1. oldValueλŠ” λ³€κ²½ μ§μ „μ˜ μ†μ„±μ˜ 값이고, newValueλŠ” λ³€κ²½ 이후 μ†μ„±μ˜ κ°’μž…λ‹ˆλ‹€.
  3. νŒŒλΌλ―Έν„°λŠ” ν΄λ‘œμ €λ‘œ, κ°’ λ³€κ²½μ‹œ μˆ˜ν–‰ν•  λ™μž‘μ„ μ •μ˜ν•΄μ•Όν•©λ‹ˆλ‹€.

결둠은 첫번째 νŒŒλΌλ―Έν„°μ—μ„œ λ°›λŠ” 것은 κ°μ‹œμž 역할을 ν•˜λŠ” μ˜€λΈŒμ νŠΈκ°€ μ „λ‹¬μ΄λ˜κ³  λ‘λ²ˆμ§Έ νŒŒλΌλ―Έν„°μ— NSKeyValueObservedCange<Value> νƒ€μž…μ˜ 값이 λ“€μ–΄μ˜€λŠ”λ°, 이 κ°’μ—μ„œ oldValue와 newValue에 μ ‘κ·Ό ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ§Œμ•½ observe λ©”μ„œλ“œμ˜ options νŒŒλΌλ―Έν„°μ— 아무것도 μ „λ‹¬λ˜μ§€ μ•ŠλŠ”λ‹€λ©΄, nil둜 값이 μ΄ˆκΈ°ν™”λ©λ‹ˆλ‹€.

본격! μ‚¬μš©λ°©λ²•!

Model κ°μ²΄μ—μ„œ 값이 λ³€κ²½ λ˜μ—ˆμ„ 경우, λ³€κ²½λœ 값을 UI 에 λ°˜μ˜ν•΄μ•Όν•©λ‹ˆλ‹€. μ΄λ•Œ μ»¨νŠΈλ‘€λŸ¬κ°€ λͺ¨λΈ 객체에 observing을 λ„μž…, λΈλ¦¬κ²Œμ΄νŠΈμ— 메세지λ₯Ό 보내 μ²˜λ¦¬ν•˜κ²Œν•΄μ•Όν•©λ‹ˆλ‹€.

class Person: NSObject {
		@objc dynamic var name: String
		
		init(name: Stirng) {
				self.name = name
		}
}

var person = Person(name: "Junha")
person.observe(\.name, options: [.old, .new]) { (object, change) in
		print("name changed form \(change.oldValue) to \(change.newValue)")
}

person.name = "μ€€ν•˜" // Name changed from Optional("Junha") to Optional("도리")

// 예제 좜처[https://velog.io/@jee/KVO-Key-Value-Observing]

ν”„λ‘œνΌν‹° 값이 Junhaμ—μ„œ μ€€ν•˜λ‘œ λ³€κ²½λ˜μ–΄μ„œ Observer의 change handlerκ°€ 호좜 ν–ˆκΈ° λ•Œλ¬Έμ— handler λ‚΄μ˜ oldValue와 newValueλ₯Ό κ°€μ Έμ˜¬ 수 있게 λœλ‹€.

그리고 Option에 old/new 말고도 initialκ³Ό priorκ°€ 있으며 μ„€λͺ…은 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

  • old

    • λ³€κ²½ μ „ κ°’
  • new

    • λ³€κ²½ ν›„ κ°’
  • initial

    • Observer 등둝 μ „ handler 호좜 μ‹œ (newValue둜 λ“€μ–΄κ°‘λ‹ˆλ‹€)
    • 예제
    var person = Person(name: "junha")
    person.observe(\.name, options: [.old, .new, .initial]) { (object, change) in
    		print("name changed form \(change.oldValue) to \(change.newValue)")
    }
    
    // Name changed from nil to Optional("junha")
  • prior

    • λ³€κ²½ μ „, ν›„ μƒνƒœ λͺ¨λ‘ νŒŒμ•…μ‹œ
    • 예제
    var person = Person(name: "junha")
    person.observe(\.name, options: [.old, .new, .prior]) { (object, change) in
        print("Name changed from \(change.oldValue) to \(change.newValue)")
    }
    
    person.name = "μ€€ν•˜"
    
    // Name changed from Optional("junha") to nil
    // Name changed from Optional("junha") to Optional("μ€€ν•˜")

KVO의 μž₯점

  1. 두 객체 κ°„μ˜ 동기화
    1. Modelκ³Ό View 같이 λΆ„λ¦¬λœ νŒŒνŠΈκ°„μ˜ λ³€κ²½ 사항 전달
  2. λ‚΄λΆ€ μ†ŒμŠ€ λ³€κ²½ 없이, μƒνƒœ 변화에 λŒ€μ‘ν•  수 μžˆλ‹€
  3. λ³€κ²½ μ „/ν›„ 값을 νŒŒμ•…ν•  수 μžˆλ‹€

KVO의 단점

  1. Objc λŸ°νƒ€μž„μ— 의쑴 및 클래슀만 κ΅¬ν˜„ κ°€λŠ₯ (NSObject 상속)
  2. dealloc될 λ•Œ μ˜΅μ €λ²„λ₯Ό μ§€μ›Œμ€˜μ•Ό ν•œλ‹€.

KVO μ™œ μ‚¬μš©ν•˜λŠ”λ°?

  1. RxSwift의 Subscribe 처럼 논리적인 뢄리가 κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.
    1. μ˜ˆμ‹œ
      1. ViewModel의 μ–΄λ–€ ν”„λ‘œνΌν‹°κ°€ λ³€ν™”λ₯Ό ν•˜μ˜€μ„ λ•Œ, viewμ—μ„œμ˜ λ³€ν™”λ₯Ό μœ λ„ν•  λ•Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.
      2. ν•˜μ§€λ§Œ KVO의 경우 objc λŸ°νƒ€μž„μ„ μ΄λ™ν•˜κΈ° λ•Œλ¬Έμ— classκ°€ finalμ΄κ±°λ‚˜ static dispatch둜 μ‚¬μš©μ΄ κ°€λŠ₯ν•  λ•Œ, λͺ¨λ‘ objc의 λŸ°νƒ€μž„μ„ μ΄μš©ν•΄ dynamic dispatchλ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€λ©΄ μ„±λŠ₯에 쑰금 λ–¨μ–΄μ§ˆ 것 κ°™μŠ΅λ‹ˆλ‹€.
  2. 제일 큰 μž₯점은 λ‚΄λΆ€μ˜ μ½”λ“œλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³  μ™ΈλΆ€μ—μ„œ ν•΄λ‹Ή κ°’μ˜ λ³€ν™”λ₯Ό κ΄€μ°°ν•΄μ„œ λ™μž‘ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€.
    1. λΉ„μŠ·ν•œ κΈ°λŠ₯으둜 willSetκ³Ό didSet의 κ²½μš°μ—λŠ” class 내뢀에 κ΅¬ν˜„ν•΄μ•Όν•˜μ§€λ§Œ KVOλ₯Ό μ΄μš©ν•œλ‹€λ©΄ 논리적인 뢄리가 κ°€λŠ₯ν•΄μ„œ μ™ΈλΆ€μ—μ„œ κ΄€μ°°ν•˜λŠ” 것이 κ°€λŠ₯ν•΄μ§‘λ‹ˆλ‹€.
    2. μ™ΈλΆ€ 라이브러리 λ˜λŠ” 남이 μ§  μ½”λ“œ λ˜λŠ” SDKλ₯Ό μ΄μš©ν•˜λŠ” λ‚΄λΆ€μ˜ μ½”λ“œλ₯Ό 건듀이기 νž˜λ“  μƒν™©μ—μ„œ NSObjectλ₯Ό 상속받고 접근이 κ°€λŠ₯ν•˜λ‹€λ©΄ μ™ΈλΆ€μ—μ„œ κ΄€μ°°ν•  수 μžˆλŠ” 섀계λ₯Ό ν•  수 μžˆμ–΄μ„œ μš©μ˜ν•©λ‹ˆλ‹€.
      1. ν•˜μ§€λ§Œ 이제 이것도 NSObjectλ₯Ό 상속 λ°›κ³  @objc dynamic으둜 Objc λŸ°νƒ€μž„ 쀑에 접근이 κ°€λŠ₯ν•  κ²½μš°μ—λ§Œ λœλ‹€λŠ” 것 μ•Œμ•„μ£Όμ„Έμš”.
  3. κΈ°μ‘΄ λ‚΄μž₯ ν”„λ ˆμž„μ›Œν¬μ—μ„œ 아직 objc μ½”λ“œκ°€ swift둜 μ „λ‹¬λ˜μ§€ μ•Šμ€ κ³³μ—μ„œλŠ” KVOλ₯Ό μ‚¬μš©ν•΄μ„œ 접근이 κ°€λŠ₯ν•œ 것듀이 μžˆμŠ΅λ‹ˆλ‹€.
    1. 예λ₯Ό λ“€μ–΄μ„œ AVFoundation같은 것듀은 λ‚΄λΆ€ λ³€μˆ˜λ“€μ„ μ°Έμ‘°ν• λ•Œ, μ‚¬μš©ν•˜λŠ” κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

κΈ΄κΈ€ μ½μ–΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€~~^^