Сортировка объектов в NSMutableArray с помощью sortUsingComparator

У меня есть следующий изменяемый массив:

NSMutableArray *persons = [[NSMutableArray alloc]initWithObjects:person1, person2, person3, nil];

где каждый человек является объектом, который содержит (NSInteger) personAge и (NSString *) personName свойства. Теперь я хочу отсортировать этот массив с помощью personAge. Поэтому я попробовал следующее:

[persons sortUsingComparator:
     ^NSComparisonResult(id obj1, id obj2)
     {
         Person *p1 = (Person*)obj1;
         Person *p2 = (Person*)obj2;

        return [p1.personAge compare: p2.personAge];

     }];

    NSLog(@"%ld", [persons componentsJoinedByString:@" "]);

Но я получаю сообщение ошибки "NSInteger" (aka "long" ) "Плохой приемник типа" в обратной линии. Также у меня есть предупреждение в строке NSLog: "Формат задает тип" long ", но аргумент имеет тип" NSString * ". Как это исправить?

Ответ 1

не следует использовать вместо этого что-то подобное?

[persons sortUsingComparator:
      ^NSComparisonResult(id obj1, id obj2){

             Person *p1 = (Person*)obj1;
             Person *p2 = (Person*)obj2;
             if (p1.personAge > p2.personAge) {
                return (NSComparisonResult)NSOrderedDescending;
            }

            if (p1.personAge < p2.personAge) {
                return (NSComparisonResult)NSOrderedAscending;
            }
            return (NSComparisonResult)NSOrderedSame;
    }
];

Дело в том, что вы полагаетесь на метод compare, который не существует на NSInteger: это только typedef из int. Таким образом, вы хотите сравнить целочисленное значение вместо этого и возвращает значение NSComparisonResult, чтобы соответственно обозначить порядок вашего объекта.

Ответ 2

Вы пытаетесь вызвать compare: на NSInteger, который не является объектом; это typedef для целочисленного типа (либо int, либо long в зависимости от архитектуры).

Кроме того, componentsJoinedByString: возвращает NSString, а не целое число.

Try:

[persons sortUsingComparator:
    ^NSComparisonResult(id obj1, id obj2)
    {
        Person *p1 = (Person*)obj1;
        Person *p2 = (Person*)obj2;

        if (p1.personAge < p2.personAge)
            return NSOrderedAscending;
        if (p1.personAge > p2.personAge)
            return NSOrderedDescending;
        return NSOrderedSame;
 }];

NSLog(@"%@", [persons componentsJoinedByString:@" "]);

Ответ 3

Что касается ошибки "Плохой приемник...", NSInteger - это примитивный тип данных (не класс Objective-C), поэтому вы не можете вызывать методы на нем. что вы хотите сделать, это следующее:

if (p1.personAge > p2.personAge) {
    return (NSComparisonResult)NSOrderedDescending;
}

if (p1.personAge < p2.personAge) {
    return (NSComparisonResult)NSOrderedAscending;
}
return (NSComparisonResult)NSOrderedSame;

Предупреждение связано с тем, что @"%ld" является строкой формата long (как предупреждает предупреждение), но -componentsSeparatedByString: возвращает объект NSString. Правильная строка формата для любого объекта Objective-C равна @"%@", поэтому строка должна читать NSLog(@"%@", [persons componentsJoinedByString:@" "]);.

Ответ 4

[YOURMutableArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

Ответ 5

Как и ответ tigeguero, но более аккуратный:

 [people sortUsingComparator:
      ^NSComparisonResult(Person* p1, Person* p2){

            if (p1.personAge > p2.personAge) {
                return NSOrderedDescending;
            }
            else if (p1.personAge < p2.personAge) {
                return NSOrderedAscending;
            }
            else{
                return NSOrderedSame;
            } 
    }
 ];