2009-08-06 11 views
26

मेरे पास डेटाबेस मॉडल क्लास है जो NSObject है। मेरे पास NSMutableArray में इन ऑब्जेक्ट्स का एक सेट है। मैं एक मैच खोजने के लिए indexOfObject: का उपयोग करता हूं। समस्या मॉडल ऑब्जेक्ट का मेमोरी एड्रेस चेंज है। इसलिए मैं मॉडल की पंक्ति आईडी वापस करने के लिए hash विधि को ओवरराइड कर रहा हूं। हालांकि यह ठीक नहीं करता है। मुझे hash विधि के मान की तुलना करने के लिए isEqual: विधि को ओवरराइड करना होगा।NSObject isEqual क्या है: और हैश डिफ़ॉल्ट फ़ंक्शन?

isEqual: विधि डिफ़ॉल्ट रूप से समानता निर्धारित करने के लिए क्या उपयोग करती है?

मुझे लगता है कि यह स्मृति पता का उपयोग करता है। isEqual: दस्तावेज पढ़ने के बाद मैंने सोचा कि यह hash विधि से मूल्य का उपयोग करता है। जाहिर है, ऐसा नहीं है क्योंकि उस मूल्य को ओवरराइड करने का मेरा प्रयास मेरी प्रारंभिक समस्या को हल नहीं करता है।

+0

यहां कुछ सट्टा जवाब दिए गए हैं। क्या कोई वास्तविक दस्तावेज प्रदान कर सकता है कि डिफ़ॉल्ट है एक्वाल्स पते का उपयोग करता है> मैं सुझाव नहीं दे रहा हूं कि यह नहीं है, बस इसे घोड़े के मुंह से सुनना चाहूंगा। – DougW

+0

@DougW मैंने इस पर आपकी भावनाओं को साझा किया, इसलिए मैंने एक आधिकारिक संदर्भ को ट्रैक किया और इसे स्वीकृत उत्तर में संपादित किया। –

+0

आप NSObject प्रोटोकॉल के लिए दस्तावेज़ पढ़ रहे हैं, एनएसओब्जेक्ट क्लास नहीं। प्रोटोकॉल परिभाषित करता है कि विधियों को क्या करना चाहिए, कक्षा वास्तव में परिभाषित करने में विफल रहता है कि यह वास्तव में क्या करता है। समानता और हैश को ओवरराइड करना हमेशा सुरक्षित होता है कि आप उन्हें कैसे काम करना चाहते हैं। –

उत्तर

26

जैसा कि आपने सही ढंग से अनुमान लगाया है, NSObject का डिफ़ॉल्ट isEqual: व्यवहार वस्तु के स्मृति पते की तुलना कर रहा है। अजीब, यह वर्तमान में NSObject Class Reference में प्रलेखित है नहीं, लेकिन यह Introspection प्रलेखन, जिसमें कहा गया है में दर्ज है:

isEqual: के डिफ़ॉल्ट NSObject कार्यान्वयन बस सूचक समानता के लिए जाँच करता है।

बेशक

, जैसा कि आप निस्संदेह बारे में जानते हैं, NSObject की उपवर्गों अलग तरीके से व्यवहार करने के लिए isEqual: ओवरराइड कर सकते हैं। उदाहरण के लिए, NSString की isEqual: विधि, जब कोई अन्य NSString पारित किया गया, तो पहले पता जांच लेंगे और फिर तारों के बीच सटीक शाब्दिक मिलान की जांच करेगा।

+0

इसके लिए एक संदर्भ अच्छा होगा। –

+1

... इसलिए मैंने एक जोड़ा। आश्चर्यजनक रूप से, 'एनएसओब्जेक्ट' वर्ग संदर्भ में 'isEqual: 'के लिए एक प्रविष्टि भी नहीं है, अकेले अपने व्यवहार का वर्णन कहीं भी करें, जो एक चमकदार चूक की तरह दिखता है। मैं दस्तावेजों के 'वैचारिक' खंड में कुछ अस्पष्ट पृष्ठ में आधिकारिक संदर्भ को ट्रैक करने में सक्षम था। –

+0

ऐप्पल दस्तावेज उन मामलों के साथ छेड़छाड़ कर रहा है जहां कक्षा दस्तावेज में प्रोटोकॉल विधियों को दस्तावेज नहीं किया गया है। (Superclass विधियों का उल्लेख नहीं है।) किसी दिए गए विधि के लिए दस्तावेज़ीकरण खोजने के लिए आपको अक्सर बहुत सारे चट्टानों को देखना पड़ता है। –

4

मुझे लगता है कि NSObjectisEquals== ऑपरेटर का उपयोग करता है, और hash मेमोरी पता का उपयोग करता है।

isEquals विधि को समानता के लिए पूर्ण परीक्षण के रूप में कभी भी hash का उपयोग नहीं करना चाहिए। यदि आप पर्याप्त वस्तुओं की खोज करते हैं (केवल 2^32 अलग-अलग ऑब्जेक्ट्स बनाएं, और उनमें से कम से कम दो hash) हों, तो यह दो ऑब्जेक्ट्स को समान hashCode रखने की गारंटी है।

दूसरे शब्दों में, hash को निम्न spec की आवश्यकता है: यदि दो ऑब्जेक्ट बराबर हैं, तो उनके hash बराबर होने की आवश्यकता है; हालांकि, यदि दो ऑब्जेक्ट्स 'hash मान बराबर हैं, तो वे आवश्यक रूप से बराबर नहीं हैं।

एक टिप के रूप में, आपको हमेशा isEquals और hashCode ओवरराइड करना चाहिए।

+21

"मुझे लगता है" के साथ एक जवाब शुरू करने के लिए एक दुर्भाग्यपूर्ण बात है ... –

8

isEqual: के डिफ़ॉल्ट कार्यान्वयन के बारे में उत्तर व्यापक है। इसलिए मैं hash के डिफ़ॉल्ट कार्यान्वयन के बारे में अपना नोट जोड़ता हूं। संदेश यह है:

-(unsigned)hash {return (unsigned)self;} 

यानी यह जो isEqual: में प्रयोग किया जाता है सिर्फ एक ही सूचक मूल्य है।यहाँ कैसे आप इस बाहर की जाँच कर सकते हैं:

obj: <NSObject: 0x16d44010> 
hash: 16d44010 

बेस्ट सादर:

NSObject *obj = [[NSObject alloc] init]; 
NSLog(@"obj: %@",obj); 
NSLog(@"hash: %x",obj.hash); 

परिणाम कुछ इस तरह हो जाएगा।

आईओएस में बीटीडब्ल्यू 8 hash एक संपत्ति नहीं बन गई, लेकिन यह वहां है।

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