如何比较 Objective-C 中的对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/876866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I compare objects in Objective-C?
提问by TalkingCode
How do I compare two objects of a custom class? My idea was to add an additional method to the class in which I can compare the current object with another object of the same kind.
如何比较自定义类的两个对象?我的想法是向类中添加一个额外的方法,我可以在其中将当前对象与另一个同类对象进行比较。
So I can write my own code how each field of the class is compared.
所以我可以编写自己的代码来比较类的每个字段。
This is how I would do it. Or are there some predefined methods to do that? Like "isEqualTo" of the NSString class?
这就是我要做的。或者是否有一些预定义的方法可以做到这一点?像 NSString 类的“isEqualTo”?
回答by Rob Napier
The pointers to -isEqual:are good, but if you implement -isEqual:, you absolutely mustalso implement -hashin such a way that if two objects return YESfor -isEqual:they will also return the same value for -hash. Implementing isEqual:without also implementing -hashleads to some very surprising bugs when you use Collections like NSArray.
指向的指针-isEqual:很好,但是如果你实现了-isEqual:,你绝对还必须-hash以这样一种方式实现,如果两个对象返回YESfor-isEqual:它们也将返回相同的值-hash。当您使用像 NSArray 这样的集合时,在isEqual:没有实现的情况下实现-hash会导致一些非常令人惊讶的错误。
For new developers, I tend to recommend against overloading -isEqual:. I recommend instead using the same technique as NSString, and create a custom -isEqualToFoo:(where Foois your class) until you understand the impact of -isEqual:on collections and specifically want this behavior. Overloading -isEqual:powerful, but the bugs you can create are subtle. Creating your own custom comparator is safer and clearer in many cases.
对于新开发人员,我倾向于建议不要重载-isEqual:. 我建议改为使用与 NSString 相同的技术,并创建一个自定义-isEqualToFoo:(Foo您的类在哪里),直到您了解-isEqual:对集合的影响并特别想要这种行为。重载-isEqual:功能强大,但您可以创建的错误很微妙。在许多情况下,创建自己的自定义比较器更安全、更清晰。
回答by pgb
The standard way is to override - (BOOL)isEqual:(id)anObjectand - (NSUInteger)hash.
标准方法是覆盖- (BOOL)isEqual:(id)anObject和- (NSUInteger)hash。
You should read the documentation for NSObject protocoland thisSO question has some interesting answers on how to write your hash method.
您应该阅读NSObject 协议的文档,这个问题有一些关于如何编写哈希方法的有趣答案。
回答by Georg Sch?lly
Look at the isEqual:and the compare:method.
看方法isEqual:和compare:方法。
回答by Javier Calatrava Llavería
I have the following object:
我有以下对象:
#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
What I do is overwrite base NSObject comparison methods, there's no need of reinventing the wheel and code keeps cleaner as well:
我所做的是覆盖基本的 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
Usage:
用法:
Season *season2 = [Season seasonWithYear:2010 season:kFall];
Season *season3 = [Season seasonWithYear:2009 season:kFall];
[season2 isEqual:season3];

