首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C NSArray 排序三種方式詳解:選擇器、函數指針、Block 比較器

     編輯:關於C語言

Objective-C NSArray 排序三種方式詳解:選擇器、函數指針、Block 比較器

NSArray 作為不可變數組,提供三種排序方法,本質對應兩大編程範式:內部比較(對象實現比較邏輯)與外部比較(傳入比較策略)。

一、三種排序 API 對比

方法參數類型比較邏輯位置靈活性對應 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;
}

三、關鍵類型解析

NSComparisonResult

typedef NS_ENUM(NSInteger, NSComparisonResult) {
    NSOrderedAscending  = -1L,  // 左操作數 < 右操作數(排前面)
    NSOrderedSame       = 0L,   // 相等
    NSOrderedDescending = 1L    // 左操作數 > 右操作數(排後面)
};

記憶口訣:返回負數 = 升序,返回正數 = 降序。

NSComparator (Block 類型定義)

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

四、深度對比:本質上只有兩種模式

模式一:內部比較

  • 對象類實現 compare: 方法
  • 調用:[array sortedArrayUsingSelector:@selector(compare:)]
  • 優點:類封裝比較邏輯,調用簡潔
  • 缺點:無法動態改變排序規則(如同一類對象有時升序有時降序)

模式二:外部比較

  • 傳入函數指針或 Block
  • 調用:sortedArrayUsingFunction: 或 sortedArrayUsingComparator:
  • 優點:排序策略與數據分離,極其靈活,支持上下文參數
  • 缺點:調用處代碼稍多

結論:Block 版本是函數指針版本的語法糖,本質相同,推薦現代代碼使用 Block(閉包捕獲上下文更方便)。

五、自定義類實現 compare: 示例

// 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:)];

六、總結建議

  1. 字符串、數字等基礎類型直接用 compare: 最簡潔
  2. 自定義類實現 compare: 支持預設排序
  3. 需要多種排序規則、或臨時排序時,優先使用 sortedArrayUsingComparator:(Block)
  4. context 參數可傳遞額外配置(如區分大小寫標志),Block 可直接捕獲外部變量
  5. 可變數組 NSMutableArray 對應 sortUsing... 系列方法,原地排序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved