2009-05-18 20 views
23

मैं एक कस्टम वर्ग की दो वस्तुओं की तुलना कैसे करूं? मेरा विचार कक्षा में एक अतिरिक्त विधि जोड़ना था जिसमें मैं वर्तमान वस्तु की तुलना उसी प्रकार की किसी अन्य वस्तु से कर सकता हूं।मैं उद्देश्य-सी में वस्तुओं की तुलना कैसे करूं?

तो मैं अपना खुद का कोड लिख सकता हूं कि कक्षा के प्रत्येक क्षेत्र की तुलना कैसे की जाती है।

इस तरह मैं इसे करूँगा। या क्या ऐसा करने के लिए कुछ पूर्वनिर्धारित विधियां हैं? एनएसएसटींग कक्षा के "isEqualTo" की तरह?

उत्तर

53

-isEqual: की ओर इशारा अच्छे हैं, लेकिन अगर आप -isEqual: लागू, आप पूरी तरह भी -hash इस तरह से है कि अगर दो वस्तुओं -isEqual: के लिए YES लौट वे भी -hash के लिए समान मान प्रदान करेंगे में लागू करना चाहिए। लागू करने के बिना -hash को कार्यान्वित किए बिना कुछ आश्चर्यजनक बग की ओर जाता है जब आप NSArray जैसे संग्रह का उपयोग करते हैं।

नए डेवलपर्स के लिए, मैं -isEqual: ओवरलोडिंग के खिलाफ अनुशंसा करता हूं। मैं एनएसएसटींग के समान तकनीक का उपयोग करने की बजाय अनुशंसा करता हूं, और एक कस्टम -isEqualToFoo: (जहां Foo आपकी कक्षा है) जब तक आप संग्रह पर -isEqual: के प्रभाव को समझते हैं और विशेष रूप से यह व्यवहार चाहते हैं। -isEqual: शक्तिशाली ओवरलोडिंग, लेकिन आप जो बग बना सकते हैं वे सूक्ष्म हैं। अपने स्वयं के कस्टम तुलनित्र बनाना कई मामलों में सुरक्षित और स्पष्ट है।

+0

हाय रॉब। बहुत बढ़िया जवाब! चूंकि मैं एक "नया डेवलपर" हूं, जैसा कि आपने सुझाव दिया है वैसा ही करूँगा। यह वही है जो मैंने पहली बार दिमाग में किया था। बहुत धन्यवाद। – TalkingCode

+0

इसे इंगित करने के लिए धन्यवाद। जबकि मुझे अभी भी समझ में नहीं आता है कि समानता निर्धारित करने के लिए पर्याप्त नहीं है, मुझे कुछ वास्तविक अजीब एनएससीएन्टेड एसईटी व्यवहार मिल रहा था क्योंकि मुझे नहीं पता था कि हैश सामान्य समानता परीक्षण के साथ खेल में आया था। – LucasTizma

+6

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

6

मानक तरीका - (BOOL)isEqual:(id)anObject और - (NSUInteger)hash ओवरराइड करना है।

आपको NSObject protocol और this के लिए प्रलेखन पढ़ना चाहिए SO प्रश्न में आपके हैश विधि को लिखने के बारे में कुछ दिलचस्प उत्तर हैं।

1

isEqual: और compare: विधि देखें।

0

मैं निम्नलिखित वस्तु है:

#import <Foundation/Foundation.h> 

typedef NS_ENUM(NSUInteger, SeasonType) { 
    kWinter, 
    kSpring, 
    kSummer, 
    kFall 
}; 

@interface Season : NSObject 

@property (nonatomic) SeasonType season; 
@property (nonatomic) NSUInteger year; 

+(id) seasonWithYear:(NSInteger)year season:(SeasonType)season; 
-(id) initWithYear:(NSInteger)year season:(SeasonType)season; 

@end 

मुझे क्या अधिलेखित आधार NSObject तुलना तरीकों है, वहाँ पहिया पुनर्रचना की कोई आवश्यकता नहीं है और कोड क्लीनर के रूप में अच्छी तरह से रखता है:

#import "Season.h" 

@interface Season() 

@end 

@implementation Season 

+(id) seasonWithYear:(NSInteger)year season:(SeasonType)season{ 
    return [[self alloc] initWithYear:year season:season]; 
} 

-(id) initWithYear:(NSInteger)year season:(SeasonType)season{ 
    self = [super init]; 
    if (self) 
    { 
     _year = year; 
     _season=season; 
     _baseDate=nil; 
    } 

    return self; 
} 

#pragma mark - NSObject 

- (BOOL)isEqual:(id)object { 
    if (self == object) { 
     return YES; 
    } 

    if (![object isKindOfClass:[Season class]]) { 
     return NO; 
    } 

    return [self _isEqualToSeason:(Season *)object]; 
} 

- (NSUInteger)hash { 
    return self.season^self.year; 
} 


#pragma mark - Private/Internal 

- (BOOL)_isEqualToSeason:(Season *)season { 
    if (!season) { 
     return NO; 
    } 

    return ((!self.season && !season.season) || self.season == season.season) && 
    ((!self.year && !season.year) || self.year == season.year) ; 
} 

@end 

उपयोग:

Season *season2 = [Season seasonWithYear:2010 season:kFall]; 
Season *season3 = [Season seasonWithYear:2009 season:kFall]; 
[season2 isEqual:season3]; 
संबंधित मुद्दे