Как отсортировать NSMutableArray, который содержит экземпляр NSNull - PullRequest
0 голосов
/ 23 декабря 2010

Я включил заполнитель [NSNull null] в свой массив источника данных combobox, чтобы я мог позволить пользователю выбрать «none» без фактического сохранения пустого объекта.Проблема в том, что, когда реальный объект добавляется в массив источника данных, мне нужно отсортировать массив:

[self.mutableArrayOfStrings sortUsingSelector:@selector(caseInsensitiveCompare:)];

Эта строка производит SIGKILL.

У меня та же проблемас сопутствующим массивом NSManagedObject, который также имеет заполнитель NSNull:

NSSortDescriptor *sortDescriptorName = [[NSSortDescriptor alloc] initWithKey:@“name” ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *sortDescriptorsNames = [[NSArray alloc] initWithObjects: sortDescriptorName, nil];
[self.mutableArrayOfMOs sortUsingDescriptors:sortDescriptorsNames];

Если mutableArrayOfMOs содержит объект NSNull, эта строка также создает SIGKILL.

Конечно, я мог бы скопироватьненулевые объекты в отдельный массив, сортируйте его, повторно вставьте нулевой объект и назначьте его свойству массива - но это загромождает мой код.Разве не должно быть способов сортировки, которые не давят NSNull?В конце концов, Apple явно предоставила NSNull, чтобы мы могли включать его в массивы.

Ответы [ 2 ]

4 голосов
/ 23 декабря 2010

Основная проблема в том, что NSNull сортирует как -из него до или после известного элемента? - нет общего ответа - поэтому Apple не может использовать метод общего назначения.

В вашем случае вы сортируете по sortUsingDescriptors - это берет свойство "name" из объектов в массиве - каково значение свойства "name" для NSNull?

Таким образом, используя sortUsingDescriptors, вы должны удалить NSNull, как вы описываете.

Если вы хотите сохранить NSNull в массиве, вы можете попробовать сортировку другим способом - sortUsingFunction: context: позволит вам написать функцию сравнения, которая может работать с NSNull. Код Apple имеет дело только с известными объектами, а не с тем, что они содержат.

0 голосов
/ 23 декабря 2010

Вот то, что я придумал в результате предложения itaiferber (и используя справочник типов данных Apple Foundation):

Я поместил это в файл h:

typedef NSComparisonResult (^NSComparator)(id string1, id string2);

Я добавилэтот метод:

- (NSArray *) sortNullsToTopInStringArray:(NSArray *)array {

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id string1, id string2) {       

    // First test for null object. It should go to top (beginning) of list.
    if ([string1 class] == [NSNull class])
        return (NSComparisonResult)NSOrderedAscending;

    if ([string2 class] == [NSNull class])
        return (NSComparisonResult)NSOrderedDescending;

    // For non-null strings, use regular NSString compare method, and wrap it in NSComparisonResult.
    switch ([string1 caseInsensitiveCompare:string2]) {
        case NSOrderedAscending:
            return (NSComparisonResult)NSOrderedAscending;
        case NSOrderedSame:
            return (NSComparisonResult)NSOrderedSame;
        case NSOrderedDescending:
            return (NSComparisonResult)NSOrderedDescending;
        default:
            return (NSComparisonResult)NSOrderedAscending;
    } 

}];

return sortedArray; 
}

и использовал его здесь:

NSArray *sortedArray = [self sortNullsToTopInStringArray:self.mutableArrayOfStrings];
NSMutableArray *sortedMutableArray = [sortedArray mutableCopy];
self.mutableArrayOfStrings = sortedMutableArray;
[sortedMutableArray release];

Сортировка NSManagedObjects может быть выполнена таким же образом, но я должен был бы предоставить разные методы для каждого типа сущности,чтобы извлечь строки.

Еще раз спасибо Марку и Итайферберу.

...