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

Objective-C 排序實戰與 compare: 陷阱深度解析

     編輯:關於C語言

Objective-C 排序實戰與 compare: 陷阱深度解析

Objective-C 中排序與字符串比較看似簡單,實則暗藏陷阱。本文揭示 compare: 系列方法在 nil 接收者下的隱患,並提供數字、字符串、字典、自定義對象四大場景的完整排序代碼模板。

compare: 陷阱:nil 接收者返回 nil 即 0

Objective-C 向 nil 發送消息返回 nil(即 0),而 NSOrderedSame == 0。導致:

if ([str1 compare:@"text"] == NSOrderedSame) // str1 為 nil 時條件成立!

後果:邏輯錯誤、UI 異常、數據洩漏等嚴重問題。
修正:

if (str1 != nil && [str1 compare:@"text"] == NSOrderedSame)

排序場景一:數字排序(NSString 存儲數字)

- (void)sortNumber {
    NSArray *original = @[@"8", @"41", @"32", @"11", @"-1"];
    NSComparator cmp = ^(id s1, id s2) {
        NSInteger v1 = [s1 integerValue], v2 = [s2 integerValue];
        if (v1 > v2) return NSOrderedDescending;
        if (v1 < v2) return NSOrderedAscending;
        return NSOrderedSame;
    };
    NSArray *result = [original sortedArrayUsingComparator:cmp];
    NSLog(@"%@", result); // (-1, 8, 11, 32, 41)
}

排序場景二:字符串排序(含大小寫、數字、全半角)

- (void)sortString {
    NSArray *arr = @[@"string 1", @"String 21", @"string 12", @"String 11", @"String 02"];
    NSStringCompareOptions opts = NSCaseInsensitiveSearch | NSNumericSearch 
                                | NSWidthInsensitiveSearch | NSForcedOrderingSearch;
    NSComparator cmp = ^(NSString *s1, NSString *s2) {
        return [s1 compare:s2 options:opts range:NSMakeRange(0, s1.length)];
    };
    NSArray *result = [arr sortedArrayUsingComparator:cmp];
    NSLog(@"%@", result);
}

關鍵選項:
NSCaseInsensitiveSearch 忽略大小寫
NSNumericSearch 數字按值比較("2" < "11")
NSWidthInsensitiveSearch 全半角統一
NSForcedOrderingSearch 強制排序(無歧義)

排序場景三:字典數組按 Key 排序

- (void)sortDictionary {
    NSMutableArray *arr = [NSMutableArray arrayWithObjects:
        @{@"obj0": @"0"}, @{@"obj3": @"3"}, @{@"obj1": @"1"}, 
        @{@"obj2": @"2"}, @{@"obj4": @"4"}, nil];
    NSArray *result = [arr sortedArrayUsingComparator:^NSComparisonResult(id d1, id d2) {
        NSNumber *k1 = [[d1 allKeys] firstObject];
        NSNumber *k2 = [[d2 allKeys] firstObject];
        return [k1 compare:k2]; // 升序
        // return [k2 compare:k1]; // 降序
    }];
    NSLog(@"%@", result);
}

排序場景四:自定義對象多鍵排序(NSSortDescriptor)

- (void)sortCustomObject {
    // 假設 SLPerson 有 name、age 屬性
    NSSortDescriptor *byAge = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
    NSSortDescriptor *byName = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    NSArray *result = [persons sortedArrayUsingDescriptors:@[byAge, byName]];
    // 先按 age 升序,age 相同則按 name 升序
}

最佳實踐總結

  • 比較前必須非 nil 判斷:避免 compare: 陷阱
  • Block 排序靈活:適用於複雜邏輯、基本類型轉換
  • 字符串用標準選項組合:覆蓋 90% 實際需求
  • 多鍵排序首選 NSSortDescriptor:聲明式、可讀、可維護
  • 自定義對象實現 compare: 可直接用 sortedArrayUsingSelector:

代碼下載:https://download.csdn.net/detail/u011883764/7827311

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved