在OC中,使用NSSortDescriptor可以實(shí)現(xiàn)按對象的屬性進(jìn)行排序。例如,我們有個(gè)User對象數(shù)組,想根據(jù)對象的年齡或者姓名拼音的首字母排序,就可以使用NSSortDescriptor。
首先,先簡單的看一下這個(gè)類的效果。
NSArray *array = @[@"c", @"b", @"a", @"e", @"d"];
//創(chuàng)建一個(gè)排序條件,也就是一個(gè)NSSortDescriptor對象
//第一個(gè)參數(shù)為數(shù)組中對象要按照什么屬性來排序(如自身、姓名,年齡等)
//第二個(gè)參數(shù)為指定排序方式是升序還是降序
//ascending 排序的意思,默認(rèn)為YES 升序
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:NO];
NSArray *newArray = [array sortedArrayUsingDescriptors:@[sort]];
NSLog(@"%@", newArray);

排序效果
sortedArrayUsingDescriptors: 這個(gè)方法的參數(shù)是一個(gè)數(shù)組,可以將多個(gè)排序條件放到數(shù)組中,按先后順序,先加入的優(yōu)先級高。
新建一個(gè)User類,User.h代碼如下
/** 姓名 */
@property (nonatomic, copy) NSString *name;
/** 年齡 */
@property (nonatomic, assign) NSInteger age;
- (instancetype) initWithName:(NSString *)name Age:(NSInteger)age;
User.m代碼如下
- (instancetype) initWithName:(NSString *)name Age:(NSInteger)age
{
self = [super init];
if (self) {
self.name = name;
self.age = age;
}
return self;
}
接下來我們看一下在ViewController中的具體實(shí)現(xiàn):
// 創(chuàng)建5個(gè)user對象
User *user1 = [[User alloc] initWithName:@"MM" Age:8];
User *user2 = [[User alloc] initWithName:@"MM" Age:3];
User *user3 = [[User alloc] initWithName:@"AA" Age:2];
User *user4 = [[User alloc] initWithName:@"SS" Age:7];
User *user5 = [[User alloc] initWithName:@"GG" Age:5];
// 將創(chuàng)建好的對象放入數(shù)組中,等待排序
NSArray *userArr = @[user1, user2, user3, user4, user5];
// 創(chuàng)建兩個(gè)排序條件,分別按照姓名首字母排序和年齡排序
NSSortDescriptor *des1 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSSortDescriptor *des2 = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:NO];
// 將兩個(gè)排序條件添加到數(shù)組中
NSArray *newUserArr = [userArr sortedArrayUsingDescriptors:@[des1, des2]];
// 循環(huán)輸出一下得到的新數(shù)組
for (User *user in newUserArr) {
NSLog(@"姓名:%@ -- 年齡:%@", user.name, user.age);
}

排序效果
sortedArrayUsingSelector:這個(gè)方法的參數(shù)是一個(gè)方法,我們可以自定義自己的排序規(guī)則
修改User類,在User.h中增加聲明一個(gè)方法,代碼如下:
/** 姓名 */
@property (nonatomic, copy) NSString *name;
/** 年齡 */
@property (nonatomic, assign) NSInteger age;
- (instancetype) initWithName:(NSString *)name Age:(NSInteger)age;
// 增加聲明的方法,用于自定義排序方法
- (NSComparisonResult)compareByAge:(User *)otherUser;
在User.m中實(shí)現(xiàn)該方法:
- (instancetype) initWithName:(NSString *)name Age:(NSInteger)age
{
self = [super init];
if (self) {
self.name = name;
self.age = age;
}
return self;
}
- (NSComparisonResult)compareByAge:(User *)otherUser
{
// _age 為 User的屬性
if (_age > [otherUser age]) {
return NSOrderedAscending;
} else if(_age == [otherUser age]) {
return NSOrderedSame;
} else{
return NSOrderedDescending;
}
}
在ViewController中的實(shí)現(xiàn)也修改一下:
// 創(chuàng)建5個(gè)user對象
User *user1 = [[User alloc] initWithName:@"MM" Age:8];
User *user2 = [[User alloc] initWithName:@"MM" Age:3];
User *user3 = [[User alloc] initWithName:@"AA" Age:2];
User *user4 = [[User alloc] initWithName:@"SS" Age:7];
User *user5 = [[User alloc] initWithName:@"GG" Age:5];
// 將創(chuàng)建好的對象放入數(shù)組中,等待排序
NSArray *userArr = @[user1, user2, user3, user4, user5];
// 不需要?jiǎng)?chuàng)建排序條件,而是直接調(diào)用User類中寫好的排序方法
NSArray *newUserArr = [userArr sortedArrayUsingSelector:@selector(compareByAge:)];
for (User *user in newUserArr) {
NSLog(@"姓名:%@ -- 年齡:%ld", user.name, user.age);
}
看一下執(zhí)行結(jié)果吧!

自定義排序方法結(jié)果