2009-07-23 9 views
36

मेरे पास अपने स्वयं के NSView सबक्लास के लिए बाइंडिंग लागू करने में एक दरार है। यह काम करता है, लेकिन एक निब फ़ाइल से फाइल के मालिक को बाध्य करते समय चक्र बनाए रखने में समस्याएं होती हैं। इसे पढ़ने के बाद, मुझे पता चला कि ऐप्पल को कुछ साल पहले एक ही समस्या थी, लेकिन इसे कुछ जादू अनियंत्रित वर्ग (एनएसएयूयूओटीबींडर) के साथ तय कर दिया है।क्या आप कोको बाइंडिंग मैन्युअल रूप से कार्यान्वित कर सकते हैं?

http://www.cocoabuilder.com/archive/message/cocoa/2004/6/12/109600 पर बनाए रखने की चक्र समस्या की लंबी चर्चा है। खिड़की नियंत्रक जारी किए जाने से पहले सभी बाइंडिंग को अनइंड करना है से पहले, विंडोवॉलक्लोस: जैसे स्थान पर। यह मेरे लिए एक अनावश्यक हैक की तरह लगता है।

मेरा प्रश्न यह है: क्या अनियंत्रित सुविधाओं का उपयोग किए बिना कस्टम बाइंडिंग के साथ-साथ ऐप्पल द्वारा बनाए गए कस्टम बाइंडिंग करने का कोई तरीका है? क्या मैं इस बारे में गलत तरीके से जा रहा हूं?


अद्यतन 2: मुझे एक समाधान मिला है जो मैन्युअल रूप से लागू बाइंडिंग को ऐप्पल की बाइंडिंग की तरह काम करने की अनुमति देता है। यह वास्तव में अनियंत्रित सुविधाओं का उपयोग किए बिना, अनियंत्रित NSAutounbinder क्लास का लाभ उठाता है। मैं बाद में समाधान पोस्ट करूंगा।


अद्यतन: मैं exposeBinding: का उपयोग कर की कोशिश की है, और यह कोई फर्क बनाने के लिए प्रतीत नहीं होता। हालांकि, NSObjectbind:toObject:withKeyPath:options: आधे कार्यों के कार्यान्वयन। यह बिंदी से बाइंडर में परिवर्तन (यानी मॉडल/नियंत्रक से देखने के लिए) का प्रचार करता है, लेकिन विपरीत तरीके से काम नहीं करता है। इसके अलावा, हालांकि स्पष्ट रूप से देखा जा रहा है, observeValueForKeyPath:ofObject:change:context: कभी ट्रिगर नहीं किया जाता है।

उदाहरण यहाँ परियोजना: http://www.tomdalling.com/wp-content/BindingsTest.zip

एप्पल के प्रलेखन इंगित करता है आप करते हैं, वास्तव में, मैनुअल बाइंडिंग को लागू करने के bind:toObject:withKeyPath:options: ओवरराइड करने के लिए है। यहाँ देखें: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html


साइड नोट: मैं जाँच की है कि गैर-दस्तावेजी NSAutounbinder काम करता है, और यहाँ मैं क्या पता है।

जब एक एनएसविंडो कंट्रोलर को बाध्यकारी बनाया जाता है, तो बाध्य वस्तु वास्तव में एनएसयूंडोनाइंडर है जिसे एनएसविंडो कंट्रोलर से प्राप्त किया जाता है - [NSWindowController _autounbinder]। NSWindowController ऑब्जेक्ट के लिए NSAutounbinder एक गैर-बनाए रखने वाली प्रॉक्सी है। यह बरकरार चक्र की समस्या से बचने के लिए गैर-बनाए रखना है।

कब - [NSWindowController रिलीज] को कॉल किया जाता है और retountCount == 1, NSAutounbinder स्वयं को सभी बाइंडिंग को अनबिंड करता है। इससे यह सुनिश्चित होता है कि ऑब्जेक्ट को हटाए जाने से पहले कोई खतरनाक पॉइंटर्स नहीं हैं।

+0

कोकोबिल्डर नीचे है, तो आप प्रासंगिक थ्रेड http://lists.apple.com/archives/cocoa-dev/2004//Jun/msg00835.html – s4y

उत्तर

21

यहां मुझे सबसे अच्छा समाधान मिल सकता है। मैं एक अधिक विस्तृत चर्चा और डेमो कोड यहाँ मिल गया है: http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/

मूल रूप से, आप नहीं ओवरराइड bind:toObject:withKeyPath:options: या unbind: DO । चक्र बनाए रखने से बचने के लिए NSObject पर डिफ़ॉल्ट कार्यान्वयन NSAutounbinder का उपयोग करेगा। चूंकि लुई गेरबर्ग ने बताया, अभी भी ऐसी परिस्थितियां हैं जहां NSAutounbinder लात नहीं है। हालांकि, आप कम से कम साथ ही साथ ऐप्पल की बाइंडिंग पर काम कर सकते हैं।

क्योंकि bind:toObject:withKeyPath:options: का डिफ़ॉल्ट कार्यान्वयन दृश्य बदलते समय मॉडल को अद्यतन नहीं करता है, दृश्य-संचालित परिवर्तनों को मैन्युअल रूप से प्रचारित किया जाना चाहिए। बाध्य वस्तु को अद्यतन करने के लिए आवश्यक सभी जानकारी प्राप्त करने के लिए आप -[NSObject infoForBinding:] का उपयोग कर सकते हैं। मैं एक वर्ग के साथ NSObject पर अपने ही विधि जोड़ दिया है:

-(void)propagateValue:(id)value forBinding:(NSString*)binding; 

यह बाध्य वस्तु, बाध्य कुंजी पथ हो रही हैंडल, और मूल्य ट्रांसफार्मर को लागू करने। कार्यान्वयन शीर्ष पर दिए गए लिंक से उपलब्ध है।

+0

मैंने हाल ही में इस पोस्ट को खोजने से पहले संबंधित प्रश्न का उत्तर लिखा था। क्या मैं सही हूं कि 'एक्सपोज़ बाइंडिंग:' का उपयोग करके उन मामलों में काम करता है जहां दृश्य को मॉडल में बदलावों को प्रसारित करने की आवश्यकता नहीं होती है? http://stackoverflow.com/questions/366938/is-it-necessary-to-override-bindtoobjectwithkeypathoptions-in-an-nsview-subcl/7394273#7394273 – paulmelnikow

+0

'एक्सपोज़ बाइंडिंग:' वास्तव में इंटरफेस बिल्डर के बाहर कुछ भी नहीं करता अगर मुझे ठीक से याद है। यह सब आपके इंटरफेस बिल्डर जीयूआई में बाध्यकारी शो बना देता है। –

2

आप NSKeyValueBindingCreation Protocol देख सकते हैं। यह आपको कोड के माध्यम से प्रोग्रामेटिक रूप से बाइंडिंग बनाने देता है। (यदि आपको आईबीओलेट वैरिएबल का संदर्भ देने की आवश्यकता है या वे शून्य हो सकते हैं तो एक जागने के लिए काम करना याद रखें।)

+2

पर अपने उत्तर के लिए धन्यवाद, लेकिन मैं कोशिश कर रहा हूं एक कस्टम वर्ग के लिए अपने स्वयं के बाइंडिंग को लागू करने के लिए, मौजूदा बाइंडिंग का उपयोग न करें। –

+0

मुझे लगता है कि + expose बाइंडिंग है: उस प्रोटोकॉल की विधि के लिए है। मैं निश्चित रूप से गलत हो सकता था, लेकिन ऐसा लगता है कि यह आपके स्वयं के बाइंडिंग बनाने के लिए प्रलेखित और स्वीकृत तरीका है। –

+0

खुलासा बाइंडिंग का उपयोग केवल –

3

संक्षिप्त उत्तर है, नहीं, आप इसे कॉलिंग कोड में कोई कामकाज के साथ काम नहीं कर सकते हैं और महत्वपूर्ण व्यक्ति। यहां तक ​​कि एनएसयूयूटीओबिन्डर एनएसडी दस्तावेज़ और एनएसविंडो कंट्रोलर के लिए कुछ मामलों को याद करता है, अगर ऐप्पल 2 वर्गों के लिए सही तरीके से काम नहीं कर पा रहा है तो वे विशेष रूप से ऐपकिट के अंदरूनी पहुंच के बिना हमारे उन लोगों को रिग कर सकते हैं, मूल रूप से कोई मौका नहीं है।

ऐसा कहकर, दो वर्कअराउंड हैं जो खिड़की में अनबाइंडिंग से थोड़ा सा बेहतर हो सकता है।

  1. फ़ाइल के मालिक के लिए बाध्य नहीं है, लेकिन इसके बजाय निब में रूट स्तर वस्तु के रूप में एक NSObjectController खींचें करने के लिए और कहा कि करने के लिए बाध्य है, तो setContents: awakeFromNib दौरान वस्तु नियंत्रक पर।
  2. कचरा संग्रह चालू करें। यदि यह एक विकल्प है तो यह सभी ऑब्जेक्ट चक्र मुद्दों को हल करता है ;-) स्पष्ट रूप से जीसी अपने स्वयं के मुद्दों को पेश करता है, और यदि आपको 10.4 संगतता की आवश्यकता है तो यह एक गैर-स्टार्टर है।
2

mmalc के GraphicsBindings उदाहरण को अपने स्वयं के बाइंडिंग को कार्यान्वित करने के एक अच्छे उदाहरण के लिए देखें। इसे काम करने के लिए आपको NSKeyValueBindingCreation अनौपचारिक प्रोटोकॉल को लागू करने की आवश्यकता है। अपने नियंत्रकों पता है कि चीजें हैं जो बाध्य किया जा सकता है जाने के लिए, फोन + में exposeBinding (आईडी) आपके विचार की विधि प्रारंभ:

+ (void)initialize { [self exposeBinding:@"ILIKEBINDAGE"]; } 

फिर आप बाइंडिंग NSKeyValueBindingCreation में तरीकों के प्रबंधन के लिए प्रत्येक को लागू करने की आवश्यकता होगी मसविदा बनाना। आपको मूल रूप से दृश्य के लिए केवीओ सेट करने की आवश्यकता है ताकि यह पता चल सके कि एप्लिकेशन के व्यवहार के आधार पर अपडेट करना और सफाई को नियंत्रित करना (अनबिंड :)।

यह बहुत अधिक अतिरिक्त, काफी बदसूरत कोड है, इसलिए यह हो सकता है कि पारंपरिक गोंद कोड का उपयोग बेहतर काम करता है और पढ़ने में आसान है।

+1

mmalc के ग्राफिक्स बाइंडिंग उदाहरण में मैंने उल्लेख की गई चक्र समस्या को बरकरार रखा है। इसके अलावा, खुलासा बाध्यकारी: रायन Ballantyne के जवाब में चर्चा की गई है। दुर्भाग्य से –

+2

, यह एक मृत लिंक है। – uchuugaka

संबंधित मुद्दे

 संबंधित मुद्दे