Подтвердить что ты не робот

Как сравнить объекты в Objective-C?

Как сравнить два объекта пользовательского класса? Моя идея заключалась в том, чтобы добавить дополнительный класс к классу, в котором я могу сравнить текущий объект с другим объектом того же типа.

Поэтому я могу написать свой собственный код, как сравнивается каждое поле класса.

Вот как я это сделаю. Или существуют некоторые предопределенные методы? Как "isEqualTo" класса NSString?

4b9b3361

Ответ 1

Указатели на -isEqual: хороши, но если вы реализуете -isEqual:, вы также должны реализовать -hash таким образом, чтобы, если два объекта возвращаются YES для -isEqual:, они также возвратят тот же значение для -hash. Внедрение isEqual: без реализации -hash приводит к некоторым очень удивительным ошибкам при использовании таких коллекций, как NSArray.

Для новых разработчиков я рекомендую не перегружать -isEqual:. Вместо этого я рекомендую использовать тот же метод, что и NSString, и создать пользовательский -isEqualToFoo: (где Foo - ваш класс), пока вы не поймете влияние -isEqual: на коллекции и не захотите этого поведения. Перегрузка -isEqual: мощная, но ошибки, которые вы можете создать, являются тонкими. Создание собственного пользовательского компаратора во многих случаях является более безопасным и понятным.

Ответ 2

Стандартный способ - переопределить - (BOOL)isEqual:(id)anObject и - (NSUInteger)hash.

Вы должны прочитать документацию для протокол NSObject и this Вопрос SO некоторые интересные ответы о том, как написать хэш-метод.

Ответ 3

Посмотрите на методы isEqual: и compare:.

Ответ 4

У меня есть следующий объект:

#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];