Сортировка изменений основных положений данных с помощью дескрипторов сортировки для iPhone - PullRequest
5 голосов
/ 30 июня 2011

У меня есть сущность CoreData с двумя атрибутами. Один называется «position», другой называется «positionChange». Оба они являются целыми числами, где атрибут position - это текущая позиция, а positionChange - это разница между предыдущей позицией и новой позицией. Это означает, что positionChange может быть отрицательным.

Теперь я бы хотел отсортировать по positionChange. Но я хотел бы, чтобы это игнорировало отрицательные ценности. В данный момент сортирую по убыванию, что даст результат: 2, 1, 0, -1, -2. Но я хочу получить такой результат: 2, -2, 1, -1, 0.

Есть идеи, как решить эту проблему с помощью дескрипторов сортировки?


EDIT

У меня есть 2 класса, один называется DataManager, а другой содержит мою категорию NSNumber (positionChange имеет тип NSNumber).

В DataManager у меня есть метод fetchData: где я выполняю запрос на выборку с помощью дескриптора сортировки:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Я делаю еще кое-что для запроса, но это не интересно для этой проблемы.

Моя категория NSNumber должна быть точно такой же, как вы опубликовали: В .h:

@interface NSNumber (AbsoluteValueSort)
- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber;
@end

А в .м:

@implementation NSNumber (AbsoluteValueSort)

- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber
{
    return [[NSNumber numberWithFloat:fabs([self floatValue])] compare:[NSNumber numberWithFloat:fabs([otherNumber floatValue])]];
}

@end

Когда я вызываю fetchData для моего объекта DataManager, я получаю эту ошибку:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: comparePositionChange:'

Есть идеи о том, что может быть дело? Я включил мой заголовочный файл категории NSNumber в мой класс DataManager.

Ответы [ 2 ]

5 голосов
/ 30 июня 2011

Причина сбоя кода с ошибкой unsupported NSSortDescriptor selector заключается в том, что вы используете хранилище данных SQLite и пытаетесь использовать метод Какао в качестве дескриптора сортировки. В хранилище SQLite дескрипторы сортировки на лету переводятся в SQL, а сортировка выполняется SQLite. Это действительно повышает производительность, но это также означает, что сортировка выполняется в среде, не относящейся к какао, где пользовательского метода сравнения не существует. Подобная сортировка работает только для распространенных, известных методов, а не для произвольного кода Какао.

Простым решением было бы сделать выборку без сортировки, получить массив результатов и отсортировать его. Массивы можно сортировать, используя любые методы Какао, которые вы хотите, поэтому категория med200 должна быть там полезной.

Вы также можете перейти из хранилища данных SQLite в двоичное хранилище, если ваш набор данных не очень большой.

2 голосов
/ 30 июня 2011

Попробуйте, предположив, что ваш positionChange - это NSNumber:

@interface NSNumber (AbsoluteValueSort)

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber;

@end

, за которым следует:

@implementation NSNumber (AbsoluteValueSort)

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber
{
    return [[NSNumber numberWithFloat: fabs([self floatValue])] compare:[NSNumber numberWithFloat: fabs([otherNumber floatValue])]];
}

@end

, а затем выполните следующие действия:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)];

и выполните сортировкус этим дескриптором.Если вы хотите, чтобы -2 всегда было после 2 или 5 всегда после -5, вы можете изменить comparePositionChange: возвращать NSOrderedAscending в тех случаях, когда одно число является отрицательным другого.

...