4

我無法圍繞如何使用NSSortDescriptor進行任意排序。隨意排序的NSSortDescriptor

我想要做這樣的事情:

NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"@", @"#", @"!", @"&", @"r", @"a", nil]; 

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" 
                   ascending:YES 
                   comparator: 
    ^(id obj1, id obj2) { 
     NSComparisonResult comparisonResult; 
     //Some code that uses sortAlgorithm. 
     return comparisonResult; 
    } 
]; 

這將通過關鍵name這樣的對象那種與@開頭的鍵,例如將在以r開頭的任何密鑰之前出現,例如@homeradical,並且這將再次出現在以a開始的任何密鑰之前,例如, anything

以上只是一個例子。關鍵是要啓用完全的任意排序。

這是用於NSFetchedResultsController。

//代碼使用sortAlgorithm的代碼是什麼樣子?

編輯:

代碼是圍繞我試圖實現一個sortDescriptor,公關。 occulus'建議:

- (NSFetchedResultsController *)fetchedResultsController { 
    if (__fetchedResultsController) 
     return __fetchedResultsController; 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

    fetchRequest.entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:self.temporaryManagedObjectContext]; 

    //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO comparator:^(id obj1, id obj2) { 

     NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"#", @"!", @"@", @".", nil]; 

     NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1]; 
     NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1]; 
     int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar]; 
     int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar]; 

     if (idx1 < idx2) 
      return NSOrderedAscending; 
     else if (idx1 > idx2) 
      return NSOrderedDescending; 
     else 
      return NSOrderedSame; 
    }]; 

    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor]; 
    fetchRequest.fetchBatchSize = 20;   

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.temporaryManagedObjectContext sectionNameKeyPath:nil cacheName:@"Tags"]; 

    aFetchedResultsController.delegate = self; 
    self.fetchedResultsController = aFetchedResultsController; 

    [self.fetchedResultsController performFetch:nil]; 

    return __fetchedResultsController; 
} 

註釋的sortDescriptor的工作原理。

實體「標籤」的對象上肯定存在一個名爲name的屬性。但即使沒有,這似乎不是問題。 Xcode似乎甚至沒有編譯那行代碼(sortDescriptor),這聽起來很荒謬。斷點工作得很好,但不會破壞特定的代碼行。

+1

最近出現同樣的問題。我最終購買了Don's * theory *:http://stackoverflow.com/questions/4789782/nsfetchedresultscontroller-custom-sort-not-getting-called#comment5314586_4795667 –

回答

3

您需要將obj1obj2字符串的第一個字符作爲NSStrings,在您的任意排序數組中找到它們的索引,然後比較這些位置。

事情是這樣的:(把這個代碼在你^塊)

NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1]; 
NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1]; 
int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar]; 
int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar]; 

// NOTE: we haven't dealt with the case where one of the 
// chars wasn't found in the array of characters. A strategy 
// for this would need to be decided. 

if (idx1 == idx2) { 
    return NSOrderedSame; 
} 
if (idx1 < idx2) { 
    return NSOrderedAscending; 
} 
return NSOrderedDescending; 

沒有測試,可能需要一些調整。注意大寫/小寫字符的差異。

更新:似乎有使用自定義排序描述符和SQL支持的核心數據存儲的問題。有關更多信息,請參閱this question

+0

我實現了您的建議,並且爲了測試,我將源限制爲僅限於包括在sortAlgorithm數組中找到的字符。絕對沒有任何反應。甚至比我所期望的還要多:我在NSSortDescriptor的定義處設置了一個斷點,並且它從不中斷。如果我在前面或後面的指令處設置了斷點,它會中斷。 Xcode很簡單,非常不方便地跳過我的測試你的解決方案的嘗試......我想我會在發佈這條評論的同時我正在解決這個新問題,因爲這是其他人都知道的。 –

+0

我相信我上面給出的算法是正確的。正如你注意到的那樣,甚至沒有被使用/調用也可能有問題。 – occulus

+0

你可以發佈你如何實際請求排序的代碼?即您放置NSSortDescriptor的地方。這聽起來像排序描述符從來沒有被使用。你的對象有一個名爲'name'和NSString *類型的屬性嗎? – occulus