NSArray 作為不可變數組,提供三種排序方法,本質對應兩大編程範式:內部比較(對象實現比較邏輯)與外部比較(傳入比較策略)。
| 方法 | 參數類型 | 比較邏輯位置 | 靈活性 | 對應 Java 概念 |
|---|---|---|---|---|
sortedArrayUsingSelector: | SEL | 對象內部(實現 compare:) | 低(綁定類) | Comparable.compareTo() |
sortedArrayUsingFunction:context: | C 函數指針 + context | 外部函數 | 高 | Comparator 實例 |
sortedArrayUsingComparator: | NSComparator (Block) | 內聯 Block | 高(語法糖) | Comparator Lambda |
// main.m #import// 外部比較函數:降序 NSComparisonResult intSortDesc(id a, id b, void *context) { int v1 = [a intValue]; int v2 = [b intValue]; if (v1 > v2) return NSOrderedAscending; // v1 排前面 if (v1 < v2) return NSOrderedDescending; // v1 排後面 return NSOrderedSame; } int main(int argc, const char *argv[]) { @autoreleasepool { // 1. 字符串數組:使用對象自帶 compare: 選擇器(升序) NSArray *strArray = @[@"Java", @"Android", @"Object-C"]; strArray = [strArray sortedArrayUsingSelector:@selector(compare:)]; NSLog(@"字符串升序: %@", strArray); // 輸出: Android, Java, Object-C // 2. 數字數組:傳入 C 比較函數(降序) NSArray *numArray = @[@2015, @1949, @2020]; // NSNumber 箱裝 numArray = [numArray sortedArrayUsingFunction:intSortDesc context:nil]; NSLog(@"數字降序: %@", numArray); // 輸出: 2020, 2015, 1949 // 3. 數字數組:使用 Block 比較器(升序) NSArray *numArrayAsc = [numArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { int v1 = [a intValue]; int v2 = [b intValue]; if (v1 > v2) return NSOrderedDescending; if (v1 < v2) return NSOrderedAscending; return NSOrderedSame; }]; NSLog(@"數字升序: %@", numArrayAsc); // 輸出: 1949, 2015, 2020 } return 0; }
typedef NS_ENUM(NSInteger, NSComparisonResult) {
NSOrderedAscending = -1L, // 左操作數 < 右操作數(排前面)
NSOrderedSame = 0L, // 相等
NSOrderedDescending = 1L // 左操作數 > 右操作數(排後面)
};
記憶口訣:返回負數 = 升序,返回正數 = 降序。
typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
compare: 方法[array sortedArrayUsingSelector:@selector(compare:)]sortedArrayUsingFunction: 或 sortedArrayUsingComparator:結論:Block 版本是函數指針版本的語法糖,本質相同,推薦現代代碼使用 Block(閉包捕獲上下文更方便)。
// Person.h
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
- (NSComparisonResult)compare:(Person *)other;
@end
// Person.m
- (NSComparisonResult)compare:(Person *)other {
// 按年齡升序
if (self.age < other.age) return NSOrderedAscending;
if (self.age > other.age) return NSOrderedDescending;
return NSOrderedSame;
}
// 使用
NSArray *people = @[p1, p2, p3];
people = [people sortedArrayUsingSelector:@selector(compare:)];
compare: 最簡潔compare: 支持預設排序sortedArrayUsingComparator:(Block)context 參數可傳遞額外配置(如區分大小寫標志),Block 可直接捕獲外部變量NSMutableArray 對應 sortUsing... 系列方法,原地排序