KeyPath Swift में किसी ऑब्जेक्ट की प्रॉपर्टी का एक टाइप किया गया पथ है, जिसे प्रथम श्रेणी के मान के रूप में प्रस्तुत किया जाता है। KVC (Key-Value Coding) में स्ट्रिंग कुंजियों के विपरीत, KeyPath को कंपाइलर द्वारा बिल्ड समय पर जाँचा जाता है: कंपाइलर रूट ऑब्जेक्ट के प्रकार, प्रॉपर्टी के प्रकार को जानता है और गारंटी दे सकता है कि पथ मौजूद है। KeyPath का उपयोग Combine में रिएक्टिव बाइंडिंग के लिए, SwiftUI में द्विदिश बाइंडिंग के लिए और मानक पुस्तकालय में संग्रहों को सॉर्ट और फ़िल्टर करने के लिए किया जाता है। Apple Developer, 2025 के अनुसार, KeyPath Swift में फंक्शनल प्रोग्रामिंग के लिए एक मूलभूत बिल्डिंग ब्लॉक है।
मुख्य बिंदु
KeyPath Swift मानक पुस्तकालय का एक प्रकार है जो किसी ऑब्जेक्ट की प्रॉपर्टी के पथ का प्रतिनिधित्व करता है। डॉट नोटेशन (object.property) या स्ट्रिंग कुंजी (value(forKey:)) के माध्यम से मैन्युअल रूप से प्रॉपर्टी तक पहुँचने के विपरीत, KeyPath प्रथम श्रेणी का ऑब्जेक्ट है: इसे तर्क के रूप में पास किया जा सकता है, वेरिएबल में संग्रहीत किया जा सकता है और संयोजित किया जा सकता है।
KeyPath को बैकस्लैश और प्रॉपर्टी के पथ के साथ लिखा जाता है: \Person.name. पथ नेस्टेड हो सकता है: \Person.address.city। कंपाइलर सत्यापित करता है कि Person में name प्रॉपर्टी है और name वास्तव में String है। यदि प्रॉपर्टी मौजूद नहीं है या प्रकार गलत है, तो कोड कंपाइल नहीं होता है।
struct Person: Codable {
let name: String
let age: Int
var isActive: Bool
}
// KeyPath (केवल पढ़ना)
let namePath: KeyPath<Person, String> = \Person.name
let person = Person(name: "Alice", age: 30, isActive: true)
let name = person[keyPath: namePath]
KeyPath के माध्यम से प्रॉपर्टी तक पहुँच सबस्क्रिप्ट object[keyPath: path] के माध्यम से की जाती है। केवल पढ़ने योग्य प्रॉपर्टीज़ के लिए, KeyPath का उपयोग किया जाता है। यदि प्रॉपर्टी परिवर्तनीय (var) है, तो WritableKeyPath उपलब्ध है। संदर्भ प्रकारों के लिए, ReferenceWritableKeyPath KeyPath के माध्यम से सीधे प्रॉपर्टी को संशोधित करने की अनुमति देता है।
KeyPath में प्रॉपर्टी तक पहुँच स्तर को दर्शाने वाला एक उपप्रकार पदानुक्रम है। मूल पदानुक्रम है: AnyKeyPath → PartialKeyPath → KeyPath → WritableKeyPath → ReferenceWritableKeyPath। प्रत्येक उपप्रकार क्षमताएँ जोड़ता है।
KeyPath — केवल पढ़ना। WritableKeyPath — मान प्रकारों (struct) के लिए पढ़ना और लिखना। ReferenceWritableKeyPath — संदर्भ प्रकारों (class) के लिए पढ़ना और लिखना। Swift संदर्भ के आधार पर स्वचालित रूप से सही उपप्रकार चुनता है।
| प्रकार | पहुँच | ऑब्जेक्ट प्रकार | परिवर्तन |
|---|---|---|---|
| KeyPath | केवल पढ़ना | कोई भी | नहीं |
| WritableKeyPath | पढ़ना और लिखना | मान प्रकार (inout) | mutating संदर्भ के माध्यम से |
| ReferenceWritableKeyPath | पढ़ना और लिखना | संदर्भ प्रकार | सीधा असाइनमेंट |
// WritableKeyPath मान प्रकार के लिए
var mutablePerson = Person(name: "Bob", age: 25, isActive: false)
let writablePath: WritableKeyPath<Person, Bool> = \Person.isActive
mutablePerson[keyPath: writablePath] = true
// ReferenceWritableKeyPath क्लास के लिए
class User: NSObject {
@objc dynamic var name: String = ""
}
let user = User()
let refPath: ReferenceWritableKeyPath<User, String> = \User.name
user[keyPath: refPath] = "Charlie"
एक महत्वपूर्ण अंतर: मान प्रकारों के लिए, KeyPath के माध्यम से सेट करने के लिए var (inout संदर्भ) की आवश्यकता होती है, जबकि संदर्भ प्रकारों के लिए केवल एक परिवर्तनीय प्रॉपर्टी की आवश्यकता होती है। यह Swift की सामान्य शब्दार्थ के अनुरूप है: मान प्रकार मान द्वारा पास किए जाते हैं, इसलिए परिवर्तन के लिए कंटेनर की परिवर्तनीयता आवश्यक है।
KeyPath Combine और SwiftUI में केंद्रीय भूमिका निभाता है। Combine में, assign ऑपरेटर प्रकाशक के मान को ऑब्जेक्ट की प्रॉपर्टी से बाइंड करने के लिए KeyPath का उपयोग करता है। SwiftUI में, Binding मॉडल और व्यू के बीच द्विदिश लिंकिंग के लिए KeyPath का उपयोग करता है।
assign(to:on:) ऑपरेटर एक ReferenceWritableKeyPath और एक ऑब्जेक्ट स्वीकार करता है। जब प्रकाशक मान उत्सर्जित करता है, तो यह स्वचालित रूप से निर्दिष्ट प्रॉपर्टी में लिखा जाता है। यह मैन्युअल असाइनमेंट के बिना स्थिति प्रबंधित करने का एक घोषणात्मक तरीका है।
import Combine
class SettingsViewModel: ObservableObject {
@Published var volume: Float = 0.5
var cancellables = Set<AnyCancellable>()
func bindSlider(publisher: AnyPublisher<Float, Never>) {
publisher
.assign(to: \SettingsViewModel.volume, on: self)
.store(in: &cancellables)
}
}
SwiftUI में, @Binding मूल और चाइल्ड व्यू को जोड़ने के लिए KeyPath का उपयोग करता है। मूल Binding(get:set:) या प्रोजेक्शन ($) के माध्यम से बनाया गया Binding
KeyPath लचीले और प्रकार-सुरक्षित सॉर्टिंग और फ़िल्टरिंग फ़ंक्शन लिखने में सक्षम बनाता है। हर बार क्लोज़र पास करने के बजाय, आप उस प्रॉपर्टी के लिए KeyPath पास कर सकते हैं जिसके द्वारा आप संग्रह को सॉर्ट करना चाहते हैं। यह कोड को साफ़ बनाता है और दोहराव को कम करता है।
फ़ंक्शन sorted
extension Sequence {
func sorted<Value: Comparable>(
by keyPath: KeyPath<Element, Value>,
ascending: Bool = true
) -> [Element] {
ascending
? self.sorted { $0[keyPath: keyPath] < $1[keyPath: keyPath] }
: self.sorted { $0[keyPath: keyPath] > $1[keyPath: keyPath] }
}
}
let sortedByName = people.sorted(by: \Person.name)
let sortedByAgeDesc = people.sorted(by: \Person.age, ascending: false)
यह कार्यान्वयन क्लोज़र लिखे बिना किसी भी Comparable प्रॉपर्टी द्वारा सॉर्ट करता है। उपनाम द्वारा सॉर्ट करने के लिए, बस KeyPath बदलें: \Person.lastName। यदि कस्टम कुंजी (जैसे, नाम की लंबाई) द्वारा सॉर्ट करना है, तो अंदर map का उपयोग किया जाता है — डेवलपर गैर-मानक मामलों के लिए अपना स्वयं का क्लोज़र लिख सकता है।
AnyKeyPath KeyPath पदानुक्रम में आधार प्रकार है जो विशिष्ट रूट और मान प्रकारों के बारे में जानकारी मिटा देता है। AnyKeyPath यह नहीं जानता कि इसे किस ऑब्जेक्ट प्रकार पर कॉल किया गया है या यह किस मान प्रकार को लौटाता है। यह संग्रहों में विषम KeyPath संग्रहीत करने और रिफ्लेक्शन के लिए उपयोगी है।
AnyKeyPath का उपयोग तब किया जाता है जब आपको विभिन्न प्रकारों की विभिन्न प्रॉपर्टीज़ के पथों की सूची संग्रहीत करने की आवश्यकता होती है। उदाहरण के लिए, UI कॉन्फ़िगरेटर में, जहाँ प्रत्येक पथ एक विशिष्ट प्रॉपर्टी कॉन्फ़िगर करता है, और प्रॉपर्टी प्रकार भिन्न हो सकते हैं। AnyKeyPath सभी पथों के साथ समान रूप से काम करने की अनुमति देता है।
protocol Configurable {
func apply(_ keyPath: any PartialKeyPath<Self>, value: any)
}
extension Configurable {
func configure(_ pairs: (any KeyPath<Self, any>, any)...) {
for (path, value) in pairs {
apply(path, value: value)
}
}
}
extension Person: Configurable { }
// AnyKeyPath के माध्यम से प्रॉपर्टीज़ कॉन्फ़िगर करने की अनुमति देता है
AnyKeyPath को मान पुनर्प्राप्त करते समय प्रकार रूपांतरण की आवश्यकता होती है, क्योंकि विशिष्ट प्रकार मिटा दिया गया है। पूर्ण प्रकार सुरक्षा के लिए, टाइप किया गया KeyPath
KeyPath KVC स्ट्रिंग कुंजियों (value(forKey:)) की तुलना में काफी अधिक कुशल है। स्ट्रिंग कुंजियाँ Objective-C runtime तंत्र के माध्यम से हल की जाती हैं, जिसमें स्ट्रिंग पार्सिंग, runtime लुकअप और प्रकार रूपांतरण शामिल है। KeyPath मूल Swift संरचनाओं पर आधारित एक स्थिर तंत्र है।
बेंचमार्क के अनुसार, KeyPath प्रॉपर्टी एक्सेस के लिए value(forKey:) की तुलना में औसतन 10-20 गुना तेज़ है। अंतर runtime लुकअप और डायनामिक डिस्पैच की अनुपस्थिति के कारण है। KeyPath पर्याप्त कंपाइलर ऑप्टिमाइज़ेशन के साथ सीधे मेमोरी में प्रॉपर्टी ऑफ़सेट तक पहुँचता है।
func readWithKeyPath(person: Person) -> String {
person[keyPath: \Person.name]
}
func readWithKVC(person: Person) -> String {
person.value(forKey: "name") as! String
}
KVC न केवल धीमा है, बल्कि प्रकार-असुरक्षित भी है: स्ट्रिंग “name” मौजूद नहीं हो सकती है और as! String कास्ट क्रैश हो सकती है। KeyPath कंपाइल समय पर प्रॉपर्टी के अस्तित्व और प्रकार शुद्धता की गारंटी देता है। प्रदर्शन-महत्वपूर्ण वर्गों (एनिमेशन, हज़ारों आइटम वाली सूचियाँ) के लिए, KeyPath एकमात्र सही विकल्प है।
अक्सर पूछे जाने वाले प्रश्न
KeyPath किसी ऑब्जेक्ट की प्रॉपर्टी का एक संकेतक है जिसे सामान्य मान के रूप में पास किया जा सकता है। person.name लिखने के बजाय, आप एक पथ \Person.name बनाते हैं और इसका उपयोग किसी भी Person इंस्टेंस पर प्रॉपर्टी पढ़ने या लिखने के लिए करते हैं।
KeyPath — केवल पढ़ना। WritableKeyPath — inout संदर्भ के माध्यम से मान प्रकारों (struct) को पढ़ने और लिखने के लिए। ReferenceWritableKeyPath — बिना अतिरिक्त शर्तों के संदर्भ प्रकारों (class) को पढ़ने और लिखने के लिए।
KeyPath का व्यापक रूप से Combine (assign(to:on:)), SwiftUI (Binding, FocusState), संग्रह सॉर्टिंग (sorted(by:)), Core Data (NSSortDescriptor) और नेस्टेड प्रॉपर्टीज़ तक सुरक्षित पहुँच के लिए उपयोग किया जाता है।
हाँ, KeyPath पूरी तरह से प्रकार-सुरक्षित है। पथ में त्रुटि (टाइपो, गलत प्रकार) runtime के बजाय कंपाइल समय पर पकड़ी जाती है। value(forKey:) स्ट्रिंग का उपयोग करता है और यदि कुंजी मौजूद नहीं है तो NSUndefinedKeyException के साथ क्रैश हो सकता है।
सीधे तौर पर नहीं — Swift स्ट्रिंग से गतिशील KeyPath निर्माण का समर्थन नहीं करता है। हालाँकि, आप स्थिर रूप से प्राप्त KeyPath को संग्रहीत और पास करने के लिए AnyKeyPath का उपयोग कर सकते हैं। स्ट्रिंग द्वारा गतिशील प्रॉपर्टी एक्सेस के लिए, Objective-C runtime के साथ value(forKey:) का उपयोग करें।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें