दिलचस्प पोस्ट
एक क्रोन लिखने के लिए जो आधी रात को एक स्क्रिप्ट चलाएगा? यह निर्धारित करने के लिए कि जब एक गिट शाखा बनाई गई थी? हेक्स NSString को NSData में परिवर्तित करना JLabel में बहुभाषी पाठ मैं जावा HTTPResponse से JSON को कैसे पार्स कर सकता हूं? कैसे अपाचे POI का उपयोग कर एक Word दस्तावेज़ बनाने के लिए? Dtexec का उपयोग कर एक SSIS पैकेज चलाना Linq में बैच बनाएं SSL प्रमाण पत्र सर्वर के नाम कैसे सुलझाए जाते हैं / क्या मैं कुंजीटोल का उपयोग कर वैकल्पिक नाम जोड़ सकता हूं? कॉलबैक क्या है? क्या #pragma एक बार संरक्षित गार्ड में शामिल है? पायथन में सप्ताह संख्या कैसे प्राप्त करें? एईएस एन्क्रिप्शन डिक्रिप्शन के लिए कोई कोको स्रोत कोड? ggplot2 – साजिश के बाहर एनोटेट Mongoose ने अपने संदर्भित मॉडल के क्षेत्र के आधार पर मॉडल पर क्वेरी को नेस्टेड किया है

प्रविष्टि / निष्कासन के लिए एक NSMutableArray को देखकर

एक वर्ग में एक संपत्ति (और उदाहरण के var) प्रकार की NSMutableArray संश्लेषित @property ( @property माध्यम से) है। यदि आप इस ऐरे का प्रयोग करते हैं:

 [myObj addObserver:self forKeyPath:@"theArray" options:0 context:NULL]; 

और फिर इस तरह सरणी में एक ऑब्जेक्ट डालें:

 [myObj.theArray addObject:NSString.string]; 

एक निरीक्षण वैल्यूफ़ोरकीपैथ … अधिसूचना नहीं भेजी गई है। हालांकि, निम्नलिखित उचित सूचना भेजता है:

 [[myObj mutableArrayValueForKey:@"theArray"] addObject:NSString.string]; 

ऐसा इसलिए है क्योंकि mutableArrayValueForKey एक प्रॉक्सी ऑब्जेक्ट देता है जो पर्यवेक्षक को सूचित करने का ध्यान रखता है।

लेकिन क्या संश्लेषित एक्सेसर्स स्वचालित रूप से ऐसे प्रॉक्सी ऑब्जेक्ट वापस नहीं लाएंगे? इसके आस-पास काम करने का सही तरीका क्या है – क्या मुझे एक कस्टम [super mutableArrayValueForKey...] लिखना चाहिए जो बस [super mutableArrayValueForKey...] आमंत्रित करता है?

Solutions Collecting From Web of "प्रविष्टि / निष्कासन के लिए एक NSMutableArray को देखकर"

लेकिन क्या संश्लेषित एक्सेसर्स स्वचालित रूप से ऐसे प्रॉक्सी ऑब्जेक्ट वापस नहीं लाएंगे?

नहीं।

इसके आस-पास काम करने का सही तरीका क्या है – क्या मुझे एक कस्टम [super mutableArrayValueForKey...] लिखना चाहिए जो बस [super mutableArrayValueForKey...] आमंत्रित करता है?

नहीं सरणी एक्सेसर्स को लागू करें जब आप इन कॉल करते हैं, तो केवीओ उचित सूचनाओं को स्वचालित रूप से पोस्ट करेगा। तो आपको बस यही करना है:

 [myObject insertObject:newObject inTheArrayAtIndex:[myObject countOfTheArray]]; 

और सही चीजें स्वचालित रूप से हो जाएगी

सुविधा के लिए, आप एक addTheArrayObject: लिख सकते हैं। यह एक्सेसर ऊपर वर्णित असली सरणी एक्सेसर्स में से एक को कॉल करेगा:

 - (void) addTheArrayObject:(NSObject *) newObject { [self insertObject:newObject inTheArrayAtIndex:[self countOfTheArray]]; } 

(आप NSObject स्थान पर, एरे में ऑब्जेक्ट के लिए उचित क्लास भर सकते हैं।)

फिर, [myObject insertObject:…] बजाय, आप [myObject addTheArrayObject:newObject]

दुर्भाग्य से, add<Key>Object: और add<Key>Object: इसके समकक्ष remove<Key>Object: हैं, आखिरी बार मैंने चेक किया है, केवल केवीओ द्वारा सेट के लिए मान्यता प्राप्त है (जैसा कि एनएसएसेट में है) गुणों को नहीं, गुणों को नहीं, इसलिए आपको मुफ्त केवीओ सूचनाएं नहीं मिलेंगी उन्हें जब तक आप उन्हें एक्सेसर्स के शीर्ष पर लागू नहीं करते जो इसे पहचानते हैं मैंने इस बारे में एक बग दर्ज किया: x-radar: // problem / 6407437

मेरे पास मेरे ब्लॉग पर सभी एक्सेसर चयनकर्ता प्रारूपों की सूची है I

मैं इस स्थिति में willChangeValueForKey और didChangeValueForKey उपयोग नहीं करेगा एक के लिए, वे यह दर्शाते हैं कि उस पथ के मूल्य में बदलाव आया है, न कि कई रिश्ते में मान बदल रहे हैं। आप willChange:valuesAtIndexes:forKey: का उपयोग करना चाहते हैं willChange:valuesAtIndexes:forKey: बजाय, अगर आप इसे इस तरह से किया था फिर भी, मैनुअल केवीओ नोटिफिकेशन का उपयोग इस तरह से खराब इनकैप्सुलेशन है। ऐसा करने का एक बेहतर तरीका addSomeObject: विधि परिभाषित कर रहा है addSomeObject: वास्तव में उस श्रेणी में जो सरणी का मालिक है, जिसमें मैन्युअल केवीओ सूचनाएं शामिल हैं इस तरह, बाहरी तरीकों जो सरणी में ऑब्जेक्ट्स जोड़ रहे हैं उन्हें बिना सरणी मालिक के केवीओ से निपटने के बारे में चिंता करने की ज़रूरत है, जो बहुत सहज नहीं होगा और अगर आप ऑब्जेक्ट्स को जोड़ना शुरू करते हैं तो यह अनावश्यक कोड और संभवतः बग हो सकता है कई स्थानों से सरणी

इस उदाहरण में मैं वास्तव में mutableArrayValueForKey: का उपयोग जारी mutableArrayValueForKey: :। मैं निष्पादनीय सरणियों के साथ सकारात्मक नहीं हूं, लेकिन मुझे यह प्रलेख पढ़ने से विश्वास है कि यह विधि वास्तव में एक नई ऑब्जेक्ट के साथ पूरी सरणी की जगह लेती है, इसलिए यदि प्रदर्शन एक चिंता का विषय है तो आप insertObject:in<Key>AtIndex: भी लागू करना चाहते हैं insertObject:in<Key>AtIndex: और removeObjectFrom<Key>AtIndex: उस श्रेणी में जो सरणी का मालिक है

जब आप बस गिनती को बदलना चाहते हैं, तो आप एक समग्र कुंजी पथ का उपयोग कर सकते हैं:

 [myObj addObserver:self forKeyPath:@"theArray.@count" options:0 context:NULL]; 

लेकिन इस बात से अवगत रहें कि एरे में कोई भी क्रमिक बदलाव नहीं होगा।

अपने खुद के प्रश्न का अपना जवाब लगभग सही है theArray बाहरी रूप से मत देना इसके बजाय, किसी भिन्न प्रॉपर्टी को घोषित करें, theMutableArray , कोई आवृत्ति चर के अनुरूप नहीं है, और इस theMutableArray को लिखें:

 - (NSMutableArray*) theMutableArray { return [self mutableArrayValueForKey:@"theArray"]; } 

नतीजा यह है कि अन्य ऑब्जेक्ट इस ऑब्जेक्ट का उपयोग कर सकते thisObject.theMutableArray को सरणी में बदलाव करने के लिए, और ये परिवर्तन thisObject.theMutableArray को ट्रिगर करता है।

अन्य जवाब बताते हैं कि यदि आप insertObject:inTheArrayAtIndex: भी लागू करते हैं, तो दक्षता बढ़ जाती है insertObject:inTheArrayAtIndex: और removeObjectFromTheArrayAtIndex: अभी भी सही हैं। लेकिन इन वस्तुओं के बारे में जानने के लिए या उन्हें सीधे कॉल करने के लिए अन्य वस्तुओं की कोई ज़रूरत नहीं है।

यदि आपको सेटर की जरूरत नहीं है तो आप नीचे दिए गए सरल फ़ॉर्म का भी उपयोग कर सकते हैं, जो समान प्रदर्शन (मेरे परीक्षणों में समान वृद्धि दर ) और कम बॉयलरप्लेट का उपयोग कर सकते हैं।

 // Interface @property (nonatomic, strong, readonly) NSMutableArray *items; // Implementation @synthesize items = _items; - (NSMutableArray *)items { return [self mutableArrayValueForKey:@"items"]; } // Somewhere else [myObject.items insertObject:@"test"]; // Will result in KVO notifications for key "items" 

यह काम करता है क्योंकि अगर सरणी mutableArrayValueForKey: कार्यान्वित नहीं होते हैं और कुंजी के लिए कोई सेटर नहीं है, तो mutableArrayValueForKey: नाम _<key> या <key> साथ एक आवृत्ति चर की खोज करेगा। यदि यह एक पाता है, तो प्रॉक्सी सभी संदेशों को इस ऑब्जेक्ट पर अग्रेषित करेगा।

इन एप्पल डॉक्स , खंड "ऑर्डरर्ड खोज पैटर्न ऑर्डरर्ड कलेक्शंस", # 3 देखें।

आपको अपने addObject: को लपेटने की आवश्यकता है addObject: willChangeValueForKey: और didChangeValueForKey: कॉल जहाँ तक मुझे पता है, NSMutableArray के लिए कोई रास्ता नहीं है कि आप किसी भी पर्यवेक्षकों के बारे में पता करने के लिए अपने मालिक को देख रहे हैं।

एक समाधान एक NSArray का उपयोग करना है और उसे डालने और निकालने से इसे खरोंच से बनाना है, जैसे

 - (void)addSomeObject:(id)object { self.myArray = [self.myArray arrayByAddingObject:object]; } - (void)removeSomeObject:(id)object { NSMutableArray * ma = [self.myArray mutableCopy]; [ma removeObject:object]; self.myArray = ma; } 

की तुलना में आप केवीओ प्राप्त कर सकते हैं और पुराने और नए सरणी की तुलना कर सकते हैं

नोट: self.myArray शून्य नहीं होना चाहिए, अन्य सरणीव्यक्तिविज्ञानी वस्तु: परिणाम भी शून्य में

मामले के आधार पर, यह समाधान हो सकता है, और जैसा कि NSArray केवल पॉइंटर्स को संचयित कर रहा है, यह अधिक ऊपरी नहीं है, जब तक कि आप बड़ी सरणियों और अक्सर आपरेशनों के साथ काम न करें