[英]How do I compare objects in Objective-C?
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”?
The pointers to -isEqual:
are good, but if you implement -isEqual:
, you absolutely must also implement -hash
in such a way that if two objects return YES
for -isEqual:
they will also return the same value for -hash
. 指向
-isEqual:
的指针是好的,但如果你实现-isEqual:
,你绝对必须实现-hash
,如果两个对象为-isEqual:
返回YES
-isEqual:
它们也将为-hash
返回相同的值。 Implementing isEqual:
without also implementing -hash
leads to some very surprising bugs when you use Collections like NSArray. 实现
isEqual:
当你使用像NSArray这样的集合时,如果没有实现-hash
会导致一些非常令人惊讶的错误。
For new developers, I tend to recommend against overloading -isEqual:
. 对于新开发人员,我倾向于建议不要重载
-isEqual:
. I recommend instead using the same technique as NSString, and create a custom -isEqualToFoo:
(where Foo
is your class) until you understand the impact of -isEqual:
on collections and specifically want this behavior. 我建议使用与NSString相同的技术,并创建一个自定义
-isEqualToFoo:
其中Foo
是您的类),直到您了解-isEqual:
对集合的影响,并特别想要这种行为。 Overloading -isEqual:
powerful, but the bugs you can create are subtle. 重载
-isEqual:
功能强大,但你可以创建的bug很微妙。 Creating your own custom comparator is safer and clearer in many cases. 在许多情况下,创建自己的自定义比较器更安全,更清晰。
The standard way is to override - (BOOL)isEqual:(id)anObject
and - (NSUInteger)hash
. 标准方法是覆盖
- (BOOL)isEqual:(id)anObject
和- (NSUInteger)hash
。
You should read the documentation for NSObject protocol and this SO question has some interesting answers on how to write your hash method. 您应该阅读NSObject协议的文档, 这个 SO问题有一些关于如何编写哈希方法的有趣答案。
查看isEqual:
和compare:
方法。
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];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.