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

SortedArrayUsingSelector, что он делает?

Я все еще новичок в objective-c и пытаюсь выяснить, что именно делает этот оператор.

[names allKeys] sortedArrayUsingSelector:@selector(compare:)];

Я знаю, что allKeys получает все ключи от моего словаря. Я знаю, что sortedArrayUsingSelector сортирует мой массив im, создающий. Тогда я называю метод сравнения, то есть где я потерял то, что это делает? Из документа на яблоке говорится, что "Возвращает значение NSComparisonResult, которое указывает, больше ли приемник, равный или меньше заданного числа". Я не понимаю, как он сортируется на основе этого метода.

4b9b3361

Ответ 1

NSArray * sortedKeys = [[names allKeys] sortedArrayUsingSelector:@selector(compare:)];

Приведенный выше код возвращает отсортированный массив ключей словаря, используя предоставленный вами селектор. Селектор фактически является функцией, которая будет вызываться на объекте, который сортируется в вашем массиве. В этом случае ваш массив содержит строки, поэтому в фактическом коде сортировки NSArray будет происходить следующее:

//...
[key1 compare:key2];
//..

Если вы передали другой селектор, скажем @selector (randomFunction:), то в коде сортировки произойдет следующее:

//..
[key1 randomFunction:key2];
//..

Так как NSString не отвечает на селектор randomFunction, вы получите ошибку. Если вы хотите создать свой собственный тип функции сравнения, вам нужно добавить категорию к классу, который содержит массив (в вашем случае категория - NSString).

Лучший способ сортировки массива - использовать оператор блока.

id mySort = ^(NSString * key1, NSString * key2){
    return [key1 compare:key2];
};


NSArray * sortedKeys = [[names allKeys] sortedArrayUsingComparator:mySort];

Причина, по которой лучше всего сортировать любые объекты, очень легко сделать.

id mySort = ^(MyObject * obj1, MyObject * obj2){
    return [obj1.title compare:obj2.title];
};


NSArray * sortedMyObjects = [myObjects sortedArrayUsingComparator:mySort];

Ответ 2

- (NSComparisonResult)compare:
{
    // if (value of firstObject) < (value of secondObject)
        // return NSOrderedAscending
    // else if (value of firstObject) == (value of secondObject)
        // return NSOrderedSame
    // else
        // return NSOrderedDescending
}

Ответ 3

Метод -sortedArrayUsingSelector: в вашем примере вызывает метод -compare: для объектов в массиве. Для некоторых объектов Apple уже реализовала метод -compare:, например, если вы читаете документацию NSString, вы найдете -compare: метод реализован. Вы также можете вызвать пользовательские методы сравнения на своих собственных объектах, если вы реализовали метод сравнения в этих объектах. Обратите внимание, что метод сравнения не нужно называть -compare: значение имеет только возвращаемое значение (NSComparisonResult) и объект, который получает метод.

Ответ 4

Вероятно, вы должны использовать caseInsensitiveCompare: в этой ситуации, так как вы, скорее всего, заказываете массив строк (ключи из словаря).

Вы предположили, что sortedArrayUsingSelector каким-то образом отделен от части кода compare:. Это не тот случай. compare: - это селектор, который используется для сортировки массива.

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

Как NSArray достигает этого, он не является общедоступным, но в корневом каталоге выбранный вами селектор используется для сравнения пар объектов из массива, результат которого сообщает их размещение в отсортированном массиве.

Ответ 5

Новый массив содержит ссылки на элементы принимающих массивов, а не их копии.
Сообщение компаратора отправляется каждому объекту в массиве и имеет в качестве единственного аргумента другой объект в массиве.
Например, массив объектов NSString можно отсортировать, используя метод caseInsensitiveCompare:, объявленный в классе NSString. Предполагая, что anArray существует, сортированную версию массива можно создать таким образом:

NSArray *sortedArray =
     [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];