2010-05-31 5 views
16

मेरे पास एक्सकोड कोडिंग के बारे में एक साधारण सवाल है लेकिन मुझे नहीं पता कि चीजें क्यों नहीं चल रही हैं। मेरे पास वस्तुओं की एक सरणी है (कस्टम ऑब्जेक्ट्स)। मैं सिर्फ यह जांचना चाहता हूं कि यह सरणी के भीतर है या नहीं। मैंने निम्नलिखित कोड का उपयोग किया:एनएसएआरएआरई में ऑब्जेक्ट विधि

NSArray *collection = [[NSArray alloc] initWithObjects:A, B, C, nil]; //A, B, C are custom "Item" objects 
Item *tempItem = [[Item alloc] initWithLength:1 width:2 height:3]; //3 instance variables in "Item" objects 
if([collection containsObject:tempItem]) { 
    NSLog(@"collection contains this item"); 
} 

मुझे लगता है कि उपर्युक्त जांच मुझे सकारात्मक परिणाम देगी लेकिन ऐसा नहीं है। इसके अलावा, मैंने जांच की कि क्या बनाई गई वस्तुएं समान हैं।

NSLog(@"L:%i W:%i H:%i", itemToCheck.length, itemToCheck.width, itemToCheck.height); 
for (int i = 0, i < [collection count], i++) { 
    Item *itemInArray = [collection objectAtIndex:i]; 
    NSLog(@"collection contains L:%i W:%i H:%i", itemInArray.length, itemInArray.width, itemInArrayheight); 
} 

कंसोल में, यह मैं क्या मिल गया है:

L:1 W:2 H:3 
collection contains L:0 W:0 H:0 
collection contains L:1 W:2 H:3 
collection contains L:6 W:8 H:2 

जाहिर tempItemcollection सरणी के अंदर है, लेकिन कुछ भी नहीं दिखाई देता है जब मैं containsObject: का उपयोग यह जाँच करने के लिए। क्या कोई मुझे कुछ दिशा दे सकता है कि मैं कौन सा हिस्सा गलत हूं? आपका बहुत बहुत धन्यवाद!

उत्तर

40

[NSArray containsObject:] के लिए दस्तावेज़ का कहना है:

इस विधि निर्धारित करता है कि anObject एक isEqual भेजकर रिसीवर में मौजूद है: से प्रत्येक रिसीवर के वस्तुओं के लिए संदेश (और करने के लिए पैरामीटर के रूप में anObject गुजर प्रत्येक isEqual: संदेश)।

समस्या यह है कि आप वस्तुओं के मूल्यों के बजाय वस्तुओं के संदर्भों की तुलना कर रहे हैं। इस विशिष्ट उदाहरण को काम करने के लिए, आपको या तो [collection containsObject:] एक चर के उदाहरण (उदा। A, B, या C) भेजने की आवश्यकता होगी, या आपको Item कक्षा में [NSObject isEqual:] विधि को ओवरराइड करने की आवश्यकता होगी।

यह वही अपने isEqual विधि कैसा लग सकता है:

- (BOOL)isEqual:(id)other { 
    if (other == self) 
     return YES; 
    if (!other || ![other isKindOfClass:[self class]]) 
     return NO; 
    if (self.length != other.length || self.width != other.width || self.height != other.height) 
     return NO; 
    return YES; 
} 

एक बेहतर कार्यान्वयन के लिए, तो आप इस question को देखने के लिए चाहते हो सकता है।

+1

ओह, क्षमा करें, "फल" के लिए केवल एक टाइपो, यह "आइटम" होना चाहिए। क्या आपका मतलब कस्टम क्लास ऑब्जेक्ट्स की तुलना में शामिल है ऑब्जेक्ट: काम नहीं करता है? – Anthony

+2

यह काम करता है, यह सिर्फ आपके कस्टम ऑब्जेक्ट के संदर्भ का उपयोग करके डिफ़ॉल्ट तुलना करता है। यदि आप ऊपर दिए गए उदाहरण में 'एएम' के बराबर 'tempItem' बनाना चाहते हैं, तो आपको बस अपनी कक्षा पर' isEqual' विधि बनाना होगा। – Senseful

+1

@ एंथनी, इस बारे में सोचें: 'NSObject', जो डिफ़ॉल्ट तुलना प्रदान करता है, जानता है कि आपके कस्टम वर्गों के लिए समानता कैसे परिभाषित की जाती है? किस गुण को ध्यान में रखना चाहिए और कौन सा नहीं? –