आप स्विफ्ट में केवीओ का उपयोग कर सकते हैं, लेकिन केवल उपवर्ग के dynamic
गुणों के लिए NSObject
। विचार करें कि आप bar
एक Foo
वर्ग की संपत्ति का निरीक्षण करना चाहते थे । स्विफ्ट 4 में, अपने उपवर्ग में संपत्ति के bar
रूप dynamic
में निर्दिष्ट करें NSObject
:
class Foo: NSObject {
@objc dynamic var bar = 0
}
फिर आप bar
संपत्ति में परिवर्तन देखने के लिए पंजीकरण कर सकते हैं। स्विफ्ट 4 और स्विफ्ट 3.2 में, यह बहुत सरल किया गया है, जैसा कि स्विफ्ट में कुंजी-मूल्य अवलोकन का उपयोग करके उल्लिखित है :
class MyObject {
private var token: NSKeyValueObservation
var objectToObserve = Foo()
init() {
token = objectToObserve.observe(\.bar) { [weak self] object, change in // the `[weak self]` is to avoid strong reference cycle; obviously, if you don't reference `self` in the closure, then `[weak self]` is not needed
print("bar property is now \(object.bar)")
}
}
}
ध्यान दें, स्विफ्ट 4 में, अब हमारे पास बैकस्लैश कैरेक्टर का उपयोग करके कीपैथ्स का मजबूत टाइपिंग है ( ऑब्जेक्ट \.bar
की bar
संपत्ति के लिए कीपाथ मनाया जा रहा है)। इसके अलावा, क्योंकि यह समापन समापन पैटर्न का उपयोग कर रहा है, इसलिए हमें पर्यवेक्षकों को मैन्युअल रूप से हटाने की जरूरत नहीं है (जब token
गुंजाइश से बाहर हो जाता है, पर्यवेक्षक हमारे लिए हटा दिया जाता है) और न ही हमें super
कुंजी को लागू करने के लिए कॉल करने के बारे में चिंता करने की ज़रूरत नहीं है मेल खाते हैं। इस विशेष पर्यवेक्षक का आह्वान करने पर ही इसे बंद किया जाता है। अधिक जानकारी के लिए, डब्लूडब्लूडीसी २०१ WW वीडियो देखें, व्हाट्स न्यू इन फाउंडेशन ।
स्विफ्ट 3 में, इसे देखने के लिए, यह थोड़ा अधिक जटिल है, लेकिन उद्देश्य-सी में जो कुछ करता है, उसके समान है। अर्थात्, आप लागू करेंगे observeValue(forKeyPath keyPath:, of object:, change:, context:)
जो (ए) सुनिश्चित करता है कि हम अपने संदर्भ से निपट रहे हैं (और ऐसा कुछ नहीं जिसे हमारे super
उदाहरण ने देखने के लिए पंजीकृत किया था); और फिर (बी) इसे या तो संभाल लें या इसे पास कर देंsuper
लागू करें, जैसा कि आवश्यक हो। और उपयुक्त होने पर एक पर्यवेक्षक के रूप में खुद को निकालना सुनिश्चित करें। उदाहरण के लिए, जब आप निपटाया जाता है तो आप पर्यवेक्षक को हटा सकते हैं:
स्विफ्ट 3 में:
class MyObject: NSObject {
private var observerContext = 0
var objectToObserve = Foo()
override init() {
super.init()
objectToObserve.addObserver(self, forKeyPath: #keyPath(Foo.bar), options: [.new, .old], context: &observerContext)
}
deinit {
objectToObserve.removeObserver(self, forKeyPath: #keyPath(Foo.bar), context: &observerContext)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &observerContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
// do something upon notification of the observed object
print("\(keyPath): \(change?[.newKey])")
}
}
ध्यान दें, आप केवल उन गुणों का निरीक्षण कर सकते हैं जिन्हें उद्देश्य-सी में दर्शाया जा सकता है। इस प्रकार, आप जेनरिक, स्विफ्ट struct
प्रकार, स्विफ्ट का निरीक्षण नहीं कर सकतेenum
प्रकार आदि का ।
स्विफ्ट 2 के कार्यान्वयन की चर्चा के लिए, नीचे मेरा मूल उत्तर देखें।
का उपयोग करते हुए dynamic
KVO को प्राप्त करने के साथ कीवर्ड NSObject
उपवर्गों में वर्णन किया गया कुंजी-मान अवलोकन की धारा अपनाने कोको डिजाइन सम्मेलनों के अध्याय कोको और ऑब्जेक्टिव-सी के साथ का उपयोग करते हुए स्विफ्ट गाइड:
की-वैल्यू ऑब्जर्विंग एक ऐसा मैकेनिज्म है जो ऑब्जेक्ट्स को अन्य ऑब्जेक्ट्स के निर्दिष्ट गुणों में परिवर्तन के बारे में सूचित करने की अनुमति देता है। जब तक वर्ग वर्ग से विरासत में मिलता है, तब तक आप स्विफ्ट क्लास के साथ अवलोकन कर सकते हैं NSObject
। स्विफ्ट में अवलोकन करने के लिए आप इन तीन चरणों का उपयोग कर सकते हैं।
आप जिस dynamic
भी संपत्ति का अवलोकन करना चाहते हैं , उसमें संशोधक जोड़ें । पर अधिक जानकारी के लिए dynamic
, डायनेमिक डिस्पैच की आवश्यकता देखें ।
class MyObjectToObserve: NSObject {
dynamic var myDate = NSDate()
func updateDate() {
myDate = NSDate()
}
}
एक वैश्विक संदर्भ चर बनाएं।
private var myContext = 0
कुंजी-पथ के लिए एक पर्यवेक्षक जोड़ें, और observeValueForKeyPath:ofObject:change:context:
विधि को ओवरराइड करें , और पर्यवेक्षक को अंदर निकालें deinit
।
class MyObserver: NSObject {
var objectToObserve = MyObjectToObserve()
override init() {
super.init()
objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if context == &myContext {
if let newValue = change?[NSKeyValueChangeNewKey] {
print("Date changed: \(newValue)")
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}
deinit {
objectToObserve.removeObserver(self, forKeyPath: "myDate", context: &myContext)
}
}
[ध्यान दें, इस केवीओ चर्चा को बाद में कोको और ऑब्जेक्टिव-सी गाइड के साथ यूजिंग स्विफ्ट से हटा दिया गया है , जिसे स्विफ्ट 3 के लिए अनुकूलित किया गया है, लेकिन यह अभी भी इस उत्तर के शीर्ष पर उल्लिखित के रूप में काम करता है।]
यह ध्यान देने योग्य है कि स्विफ्ट की अपनी मूल संपत्ति पर्यवेक्षक प्रणाली है, लेकिन यह एक वर्ग के लिए अपने स्वयं के कोड को निर्दिष्ट करता है जो अपने गुणों के अवलोकन पर किया जाएगा। दूसरी ओर, केवीओ को कुछ अन्य वर्ग की कुछ गतिशील संपत्ति में परिवर्तन देखने के लिए पंजीकृत करने के लिए डिज़ाइन किया गया है।