Objective-C compareTo:

Существует ли стандартный механизм для сравнения двух объектов в Objective-C?

Я знаю метод isEqual, но я не ищу точное равенство, а скорее меньше/ больше/ равно сравнения.

В Java есть compareTo:, который делает это, есть ли что-нибудь подобное в Objective-C?

Ответ 1

В Objective-C нет стандартного протокола для сравнения, например интерфейса Comparable<T> в Java, но некоторые классы из фреймворческой структуры определяют метод compare:.

NSString и NSNumber приведены примеры.

Если вы хотите предоставить свой собственный метод сравнения для пользовательского класса, я предлагаю вам придерживаться соглашений и предоставлять метод со следующей подписью

- (NSComparisonResult)compare:(MyClass *)object;

NSComparisonResult - это перечисление, определенное следующим образом

enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending
};
typedef NSInteger NSComparisonResult;

NSOrderedAscending означает, что левый операнд меньше правой (и из этого вы получаете остальные).

Примечание

Стоит подчеркнуть, что Objective-C и тесно связанная Foundation Framework построены на условностях. Это не просто идиоматический способ написания, поскольку иногда реализация зависит от них. Например, если вы создадите NSSortDescriptor без указания настраиваемого селектора, реализация по умолчанию вызовет compare: для объектов. (пример шляпы Дэвиду Ронквивисту для примера)

Другим примечательным примером является соглашение об именах для методов. Ожидается, что методы экземпляров, начинающиеся с init, возвращают объект с сохранением +1. Это было такое сильное соглашение, что с появлением ARC он был формализован и встроен в компилятор.

Чтобы обернуть это: соглашения всегда важны. В Objective-C иногда они являются фундаментальными.

Ответ 2

Вы должны реализовать

- (NSComparisonResult)compare:(CustomClass *)otherObject;

и верните либо NSOrderedAscending, NSOrderedDescending, либо NSOrderedSame.

Даже если NSObject не реализует его, это метод, используемый во всей системе для сравнения. Например:

NSArray *unsorted = @[[CustomClass new], [CustomClass new], [CustomClass new]];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"self" 
                                                       ascending:NO]
NSArray *sorted = [unsorted sortedArrayUsingDescriptors:@[sort]];

будет вызывать compare: в "CustomClass" и использовать результаты для сортировки массива. Обратите внимание, что если ваш класс не реализует compare:, это приведет к сбою из-за этого (при сортировке).

Ответ 3

В NSString, NSDate, NSNumber и других классах существует метод compare:. Все они возвращаются NSComparisonResult.