λ΅λ³ μμ½
Key-Value Observing μ΄λ νΉμ ν€κ°μ λ³νλ₯Ό κ°μ§νλ κΈ°λ₯μΌλ‘ κ°μ²΄ νλ‘νΌν° λ³κ²½μ¬νμ λ€λ₯Έ κ°μ²΄μκ² μ릴 μ μλ μ½μ½μ νλ μμν¬μ λ΄μ₯λμ΄ μλ ν¨ν΄μ λλ€.
λΆκ° μ€λͺ
KVC(Key-Value Coding)λ NSKeyValueCoding νλ‘ν μ½μ μν΄ λμνλ€. NSKeyValueCoding μ νΉμ§μ μ»΄νμΌ νμμ μ κ·Όνλ κ²μ΄ μλ λ¬Έμμ΄μ μ¬μ©νμ¬ λ°νμμ κ°μ²΄μ νλ‘νΌν°μ μ κ·Όνκ±°λ κ°μ μ€μ νλ€λ κ²μ΄λ€. Key-value codingμ KVO(Key Value Observing), μ½μ½μ λ°μΈλ©, μ½μ΄ λ°μ΄ν° λ± μ½μ½μ νλ μμν¬μ μμ£Ό μ μ©λλ μ리μ΄λ€.
λν NSObjectλ₯Ό μ±ννκ³ μλ μΉκ΅¬λ λͺ¨λ NSKeyValueCoding νλ‘ν μ½μ μ±ννκ³ μλ€κ³ λ³Ό μ μλ€. (λ°νμμ μ£Όμλ₯Ό μ°Ύμκ°κΈ° λλ¬Έμ κ°νμ μλ μ±νμ΄ μλμ΄ μλκ² λΉμ°νκΈ°λ νλ€) λ°λΌμ KVCλ₯Ό μ΄μ©νλ μ½μ½μ νλ μμν¬ ν¨ν΄μ NSObjectλ₯Ό μ±νν΄μΌνλ€.
import Foundation
// κ΄μ°°ν ν΄λμ€ μ μ
class Person: NSObject {
@objc dynamic var name: String
init(name: String) {
self.name = name
}
}
// μ΅μ λ² ν΄λμ€ μ μ
class NameObserver: NSObject {
var observation: NSKeyValueObservation?
init(person: Person) {
super.init()
// KVO μ€μ
observation = person.observe(
\.name, // 'name' νλ‘νΌν°μ λν κ΄μ°°
options: [.old, .new] // μ΄μ κ°κ³Ό μλ‘μ΄ κ° λ λ€ κ΄μ°°
) { object, change in
if let oldName = change.oldValue, let newName = change.newValue {
print("Name changed from \(oldName) to \(newName)")
}
}
}
}
// KVO μ¬μ© μμ
let person = Person(name: "Alice")
let observer = NameObserver(person: person) // μ΅μ λ² μμ± λ° λ±λ‘
// νλ‘νΌν° κ° λ³κ²½
person.name = "Bob" // μΆλ ₯: "Name changed from Alice to Bob"
KVO μ¬μ©λ°©λ²μ ν¬κ² 3κ°μ§ λ¨κ³λ‘ ꡬμ±λλ€.
1. κ΄μ°° λΉν ν΄λμ€(KVOλ KVCλ₯Ό μ¬μ©νκΈ° λλ¬Έμ NSObjectλ₯Ό μ±νν΄μΌν¨) λ₯Ό μ μνλ€.
2. κ΄μ°° ν ν΄λμ€(μ΅μ λ²) μ μ (κ°μ μ΄μ λ‘ NSObject μ±ν)
3. μ΅μ λ² μμ± λ° κ΄μ°°ν ν΄λμ€ λ±λ‘
λ¨Όμ κ΄μ°° λΉν ν΄λμ€λ₯Ό μ μν λλ @objc μ΄νΈλ¦¬λ·°νΈμ dynamic λͺ¨λνμ΄μ΄λ₯Ό μ μΈν΄μΌνλ€.
KVOλ KVC 맀컀λμ¦μ μ΄μ©νκ³ KVCλ Objective-C κΈ°λ° λμ λ©μ»€λμ¦μ΄λ€. μ΄ λ¬Έμ₯μ μμλλ‘ λ€μ λ°κΎΈλ©΄
"@objc(μ€λΈμ ν°λΈ-C μ΄μ©ν΄μ) dynamic(λμ μΌλ‘) μ²λ¦¬ν κ±°μ" μ μμνλ€. (μλ Swiftμ νλ‘νΌν° μ²λ¦¬ 맀컀λμ¦μ μ μ λμ€ν¨μΉλ₯Ό μ¬μ©ν¨ - μ»΄νμΌ νμ μ²λ¦¬)
λλ²μ§Έμμλ KVO μ€μ μ μν΄ NSKeyValueObservationμ μ±ννκ³ μλ observation νλ‘νΌν°λ₯Ό μ μΈν΄μ€λ€.
NSKeyValueObservationdms λ observe λ©μλκ° νΈμΆλ λλ§λ€ 리ν΄μ΄ λλ©΄μ κ°μ λ³νλ₯Ό κ΄μ°°νλ€. λν μλμΌλ‘ λ©λͺ¨λ¦¬λ₯Ό κ΄λ¦¬νλ κΈ°λ₯λ μμ΄ κ΄μ°°νλ κ°μ²΄κ° ν΄μ λλ©΄ μλμΌλ‘ μ°Έμ‘°λ ν΄μ λλ€. λ§μ½ μ§μ μ°Έμ‘°λ₯Ό ν΄μ νκ³ μΆλ€λ©΄ observation?.invalidation()μ ν¬ν¨νλ λ©μλλ₯Ό λ§λ€μ΄ μΈλΆμμ νΈμΆν΄μ€λ€.
μΈλ²μ§Έλ μ΄μ λ€μ°¨λ €μ§ λ°₯μμ μκ°λ½λ§ μ¬λ¦°λ€.
κ΄μ°°ν κ°μ²΄ νμ μ μ μΈνλ€. κ·Έλ¦¬κ³ μ΅μ λ² κ°μ²΄μλ€ κ΄μ°°ν κ°μ²΄λ₯Ό λ£μ΄μ€μΌλ‘μ¨ κ°μ²΄ λ³νλ₯Ό κ΄μ°°νλ€.
κ·Έλ λ€λ©΄ μ μ½λμμ \. μ 무μμ μλ―Έν κΉ? λ°λ‘ keyPathλ₯Ό μλ―Ένλ€. keyPathλ λ§κ·Έλλ‘ νΉμ νλ‘νΌν°μ λν κ²½λ‘λ‘ μ§μ μ μΈ νλ‘νΌν° μ΄λ¦μ μ¬μ©νμ§ μκ³ νλ‘νΌν°μ μ κ·Όν μ μλ€. νΉμ νλ‘νΌν° μ΄λ¦μ ν΅ν΄ μ§μ μ κ·Όνλ©΄ μ»΄νμΌ νμμμ νμΈνμ¬ λμ μΈ λ°μΈλ©μ΄ λΆκ°λ₯νμ§λ§ keyPathλ₯Ό νμ©νλ©΄ λμ μΈ λ°μΈλ©μ΄ λμ΄ μ°Έμ‘°λ₯Ό ν΅ν΄ λ³κ²½μ¬νμ μ λ°μ΄νΈ ν μ μκΈ° λλ¬Έμ KVO, SwfitUI λ±μμ μμ£Ό μ¬μ©λλ€.
import Foundation
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let person = Person(name: "Alice", age: 25)
// Key Path μμ±
let nameKeyPath = \Person.name // Person κ°μ²΄μ `name` νλ‘νΌν°μ λν Key Path
let ageKeyPath = \Person.age // Person κ°μ²΄μ `age` νλ‘νΌν°μ λν Key Path
// Key Pathλ₯Ό μ¬μ©νμ¬ νλ‘νΌν° κ° μ½κΈ°
let personName = person[keyPath: nameKeyPath] // "Alice"
let personAge = person[keyPath: ageKeyPath] // 25
// Key Pathλ₯Ό μ¬μ©νμ¬ νλ‘νΌν° κ° μ€μ
person[keyPath: nameKeyPath] = "Bob"
λ νΌλ°μ€
'π¦ Flutter' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
The plugin "cloud_firestore" requires a higher minimum iOS deployment version than your application is targeting. μλ¬ (1) | 2024.07.24 |
---|---|
Swiftμμ KeyPath νμ μ΄λ? (1) | 2024.06.24 |
μμ ―μ Key λ₯Ό μ¬μ©ν΄μΌνλ μ΄μ (0) | 2024.06.12 |
| WWDC 16 | Concurrent Programming with GCD (0) | 2024.06.05 |
Flutter νλ©΄μ νμμ routes μ onGenerateRoute μ μ°¨μ΄ (0) | 2024.06.04 |