如何比较Objective-C中的对象?

时间:2009-05-18 09:28:16

标签: objective-c

如何比较自定义类的两个对象?我的想法是在类中添加一个额外的方法,我可以将当​​前对象与同类的另一个对象进行比较。

所以我可以编写自己的代码,比较每个类的字段。

我就是这样做的。或者有一些预定义的方法来做到这一点?像NSString类的“isEqualTo”一样?

4 个答案:

答案 0 :(得分:54)

指向-isEqual:的指针很好,但是如果你实现-isEqual:,你绝对必须也实现-hash,如果两个对象返回对于YES-isEqual:他们也会为-hash返回相同的值。在使用像NSArray这样的集合时,实现isEqual:而不实现-hash会导致一些非常令人惊讶的错误。

对于新开发者,我倾向于建议不要重载-isEqual:。我建议使用与NSString相同的技术,并创建自定义-isEqualToFoo:(其中Foo是您的类),直到您了解-isEqual:对集合的影响并特别想要此行为。重载-isEqual:功能强大,但您可以创建的错误是微妙的。在许多情况下,创建自己的自定义比较器更安全,更清晰。

答案 1 :(得分:6)

标准方法是覆盖- (BOOL)isEqual:(id)anObject- (NSUInteger)hash

您应该阅读NSObject protocolthis的文档。所以问题对于如何编写哈希方法有一些有趣的答案。

答案 2 :(得分:1)

查看isEqual:compare:方法。

答案 3 :(得分: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];