KVO(Key-value observing)
[๊ณต์ ๋ฌธ์ ๋ฒ์ญ]
Key-value observing์ ๋ค๋ฅธ ๊ฐ์ฒด์ ์์ฑ์ ๋ํ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์ฒด์๊ฒ ์๋ฆด ๋ ์ฌ์ฉํ๋ Cocoa ํ๋ก๊ทธ๋๋ฐ ํจํด์ ๋๋ค. ๋ชจ๋ธ ๊ฐ, ๋ทฐ ๊ฐ ๋ฑ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ๋ ์ฑ์ ๋ถ๋ถ ๊ฐ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ ๋ฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค. Key-value observing์ ์ค์ง NSObject์์ ์์๋๋ ํด๋์ค์ ํจ๊ป ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ ๋ฆฌ
- Key-value Observing์ Cocoa ํ๋ก๊ทธ๋๋ฐ ํจํด
- ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด ์ฌํญ์ ๋ค๋ฅธ ๊ฐ์ฒด์ ์๋ฆฌ๋ ๋ฐ์ ์ฌ์ฉ๋จ
- ๋ชจ๋ธ๊ณผ ๋ทฐ ์ฒ๋ผ ๊ธฐ๋ฅ์ ์ผ๋ก ๋ถ๋ฆฌ๋์ด ์๋ ๋ถ๋ถ์์์ ์ ๋ณด ์ ๋ฌ์ ์ ํฉ
- KVO๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ฐ์ฒด๊ฐ NSObject๋ฅผ ์์๋ฐ์์ผ ํจ
์ฌ์ฉ ๋ฐฉ๋ฒ
1. @objc dynamic var
key-value observing ์ ํตํด ๊ด์ฐฐํ๊ณ ์ ํ๋ ํ๋กํผํฐ์ @objc ์ดํธ๋ฆฌ๋ทฐํธ์ dynamic ํค์๋๋ฅผ ๋ถ์ฌ KVO๋ฅผ ์ฌ์ฉํด ๊ด์ฐฐ๊ฐ๋ฅํ๋๋ก ํด์ค๋๋ค.
class MyObjectToObserve: NSObject {
@objc dynamic var myDate = NSDate(timeIntervalSince1970: 0) // 1970
func updateDate() {
myDate = myDate.addingTimeInterval(Double(2 << 30)) // Adds about 68 years.
}
}
์์ ์์ ์ฝ๋์ ๊ฐ์ด NSObject๋ฅผ ์์๋ฐ๋ ํด๋์ค ๋ด์ ํ๋กํผํฐ๋ฅผ @objc dynamic var๋ก ์ ์ธํด์ฃผ๋ฉด ๋ฉ๋๋ค.
2. Observer ์ ์ - observe(_:options:changeHandler:)
observer ํด๋์ค์ ์ธ์คํด์ค๋ ํ๋ ์ด์์ ํ๋กํผํฐ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
observer๋ฅผ ์ ์ํ ๋๋ ๊ด์ฐฐํ๊ณ ์ ํ๋ ํ๋กํผํฐ๋ฅผ ์ฐธ์กฐํ๋ key path๋ฅผ ๊ฐ์ง observe(_:options:changeHandler:) ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊ด์ฐฐ์ ์์ํ ์ ์์ต๋๋ค.
class MyObserver: NSObject {
@objc var objectToObserve: MyObjectToObserve
var observation: NSKeyValueObservation?
init(object: MyObjectToObserve) {
objectToObserve = object
super.init()
observation = observe(
\.objectToObserve.myDate,
options: [.old, .new]
) { object, change in
print("myDate changed from: \(change.oldValue!), updated to: \(change.newValue!)")
}
}
}
์์ ์ฝ๋๋ NSKeyValueObservatedChange ์ธ์คํด์ค์ oldValue์ newValue๋ฅผ ์ฌ์ฉํ์ฌ ๊ด์ฐฐ ์ค์ธ ํ๋กํผํฐ์ ๋ํด ๋ณ๊ฒฝ๋ ๋ด์ฉ์ ํ์ธํฉ๋๋ค.
ํ๋กํผํฐ๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋์๋์ง ์ ํ์๊ฐ ์์ผ๋ฉด options ํ๋ผ๋ฏธํฐ๋ฅผ ์๋ตํ๋ฉด ๋ฉ๋๋ค. options ํ๋ผ๋ฏธํฐ๋ฅผ ์๋ตํ๋ฉด ์๋ก์ด ํ๋กํผํฐ ๊ฐ๊ณผ ๋ณ๊ฒฝ ์ ํ๋กํผํฐ ๊ฐ์ด ์ ์ฅ๋์ง ์์ผ๋ฏ๋ก oldValue์ newValue๊ฐ nil์ด ๋ฉ๋๋ค.
NotificationCenter
[๊ณต์ ๋ฌธ์ ๋ฒ์ญ]
๋ฑ๋ก๋ ๊ด์ฐฐ์(observers)์๊ฒ ์ ๋ณด๋ฅผ ๋ธ๋ก๋์บ์คํ ํ ์ ์๋ ์๋ฆผ ๋ฐ์ก ๋ฉ์ปค๋์ฆ์ ๋๋ค.
๊ฐ์ฒด๋ ์๋ฆผ ์ผํฐ์ ๋ฑ๋กํ์ฌ addObserver(_:selector:name:object:using:) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ addObserver(forName:object:queue:using:) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆผ(= NSNotification ๊ฐ์ฒด)์ ์์ ํฉ๋๋ค.
๊ฐ์ฒด๊ฐ ์์ ์ ๊ด์ฐฐ์๋ก ์ถ๊ฐํ ๋ ์ด๋ค ์๋ฆผ์ ์์ ํด์ผ ํ๋์ง ์ง์ ํฉ๋๋ค. ๋ฐ๋ผ์ ๊ฐ์ฒด๋ ์ฌ๋ฌ ๋ค๋ฅธ ์๋ฆผ์ ๋ํด ๊ด์ฐฐ์๋ก ๋ฑ๋กํ๊ธฐ ์ํด ์ด ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๋ฒ ํธ์ถํ ์ ์์ต๋๋ค.
์คํ ์ค์ธ ๊ฐ ์ฑ์๋ default notification center๊ฐ ์์ผ๋ฉฐ, ํน์ ์ปจํ
์คํธ์์ ํต์ ์ ๊ตฌ์ฑํ๊ธฐ ์ํด ์๋ก์ด notification center๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์๋ฆผ ์ผํฐ๋ ๋จ์ผ ํ๋ก๊ทธ๋จ ๋ด์์๋ง ์๋ฆผ์ ์ ์กํ ์ ์์ต๋๋ค.
(๋ค๋ฅธ ํ๋ก์ธ์ค์ ์๋ฆผ์ ๋ฐ์ก, ์์ ํ๋ ค๋ฉด DistributedNotificationCenter๋ฅผ ์ฌ์ฉ)
Post, Observer ๋ฉ์๋
Post(์๋ฆผ์ ๋ณด๋ด๋) ๋ฉ์๋
- name: ์ ๋ฌํ๊ณ ์ถ์ ์ ํธ ์ด๋ฆ
- object: ์ ๋ฌํ๊ณ ์ถ์ ๋ฐ์ดํฐ. ์์ผ๋ฉด(์ ํธ๋ง ์ ๋ฌํ๊ณ ์ถ๋ค๋ฉด) nil
- userInfo: notification๊ณผ ๊ด๋ จ๋ ๊ฐ ๋๋ ๊ฐ์ฒด์ ์ ์ฅ์. ์์ผ๋ฉด nil
Observer(์๋ฆผ์ ๋ฐ๊ธฐ ์ํ ๊ด์ฐฐ์) ๋ฉ์๋
- observer: ๊ด์ฐฐ์๋ก ๋ฑ๋กํ ๊ฐ์ฒด
- selector: ํด๋น ์ ํธ๋ฅผ ๋ฐ์ผ๋ฉด ์คํํ ํจ์
- name: observer๋ฅผ ๋ฑ๋กํ notification ์ด๋ฆ
- object: observer๊ฐ ํด๋น object์ notification๋ง ์ ๋ฌ๋ฐ๊ณ ์ถ์ ๋ ์ง์ ๊ฐ๋ฅ. nil์ผ ๊ฒฝ์ฐ๋ ํด๋นํ๋ ์ ํธ๋ฅผ ๋ชจ๋ ๋ฐ๊ฒ ๋ค๋ ์๋ฏธ
- queue: block์ด ์คํ๋๋ ์์ ๋๊ธฐ์ด (nil์ผ ๊ฒฝ์ฐ ๋๊ธฐ์ ์ผ๋ก ์คํ)ย
- block: ์๋ฆผ์ ๋ฐ์ ๋ ์คํ๋๋ ๋ธ๋ก
์์ ์ฝ๋
class ViewController: UIViewController {
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var messageTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func tapSubscribeButton(_ sender: Any) {
NotificationCenter.default.addObserver(self, selector: #selector(dataReceived), name: NSNotification.Name("SendAlarm"), object: nil)
statusLabel.text = "๊ตฌ๋
ํจ!!!!!"
}
@IBAction func tapSendButton(_ sender: Any) {
NotificationCenter.default.post(name: NSNotification.Name("SendAlarm"), object: messageTextField.text ?? "")
}
@objc
func dataReceived(notification: NSNotification) {
if let text = notification.object as? String {
titleLabel.text = text
}
}
}
'๐ ๊ธฐ๋ก > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] 20231207 (3) | 2023.12.08 |
---|---|
[TIL] 20231206 (0) | 2023.12.08 |
[TIL] 20231204 (1) | 2023.12.04 |
[TIL] 20231130 (2) | 2023.11.30 |
[TIL] 20231129 (1) | 2023.11.29 |