관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] KVO(Key Value Observing) 사용한 subscribe 방법 (KVO 간단 사용법) 본문

iOS 응용 (swift)

[iOS - swift] KVO(Key Value Observing) 사용한 subscribe 방법 (KVO 간단 사용법)

jake-kim 2023. 10. 16. 01:57

KVO 개념

  • Key Value Observing: key는 인스턴스의 proprety를 의미하며 이 proprety가 변경되는 것을 
  • 인스턴스의 프로퍼티(속성)에 대한 변화를 감시하고, 해당 변화에 대한 알림을 받는 디자인 패턴 및 기술

KVO 간단 사용법

ex) KVO를 사용하여 버튼이 highlighted 되는 이벤트를 구독하여 count올려주는 예제

  • 뷰 준비
class ViewController: UIViewController {
    private let label = {
        let label = UILabel()
        label.text = "count: 0"
        label.font = .systemFont(ofSize: 24, weight: .regular)
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    private let myButton = {
        let button = UIButton()
        button.setTitle("myButton", for: .normal)
        button.setTitleColor(.systemBlue, for: .normal)
        button.setTitleColor(.blue, for: .highlighted)
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(label)
        view.addSubview(myButton)
        
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        ])
        NSLayoutConstraint.activate([
            myButton.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            myButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        ])
    }
}
  • UIView의 메소드인 observe(_:changeHandler:)를 사용하여 옵저빙이 가능
    • KeyPath로 입력한 property가 변경되면 changeHandler 클로저가 호출되는 방식
    • 이 메소드의 리턴값은 NSKeyValueObservation인데, 이 인스턴스의 invalidate()를 하면 옵저빙이 중지
observe(_ keyPath: KeyPath<UIView, Value>, changeHandler: <(UIView, NSKeyValueObservedChange<Value>) -> Void>) -> NSKeyValueObservation
  • keyPath에 다양한 프로퍼티가 있는데 여기서 버튼을 클릭하면 변경하는 값인 isHighlighted를 에제로 사용

myButton.observe(\.isHighlighted) { [weak self] object, _ in
    guard let self, object.isHighlighted else { return }
    count += 1
    label.text = "count: \(count)"
}
  • 전역 변수에 NSKeyValueObservation 인스턴스를 선언해놓고 특정 시점에 invalidate해서 옵저빙 제거가 가능
private var observer: NSKeyValueObservation?

observer = myButton.observe(\.isHighlighted) { [weak self] object, _ in
    guard let self, object.isHighlighted else { return }
    count += 1
    label.text = "count: \(count)"
}

deinit {
    observer?.invalidate()
}

(완성)

* 전체 코드: https://github.com/JK0369/ExKvo

* 참고

https://developer.apple.com/documentation/swift/using-key-value-observing-in-swift

https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/KVO.html#//apple_ref/doc/uid/TP40008195-CH16-SW1

Comments