2010-12-23 75 views
0

我已經在我的組合框數據源數組中包含了一個佔位符[NSNull null],所以我可以允許用戶在沒有實際存儲空白對象的情況下選擇「none」。的問題是,當一個真正的對象被添加到數據源陣列,我需要對數組進行排序:如何對包含NSNull實例的NSMutableArray進行排序

[self.mutableArrayOfStrings sortUsingSelector:@selector(caseInsensitiveCompare:)]; 

這條線產生SIGKILL。

我有與NSManagedObject的同伴陣列,其中也有一個佔位符NSNull同樣的問題:

NSSortDescriptor *sortDescriptorName = [[NSSortDescriptor alloc] initWithKey:@「name」 ascending:YES selector:@selector(caseInsensitiveCompare:)]; 
NSArray *sortDescriptorsNames = [[NSArray alloc] initWithObjects: sortDescriptorName, nil]; 
[self.mutableArrayOfMOs sortUsingDescriptors:sortDescriptorsNames]; 

如果mutableArrayOfMOs包含NSNull對象,此行也產生了SIGKILL。當然,我可以將非空對象複製到一個單獨的數組中,對其進行排序,重新插入空對象,並將其分配給數組屬性 - 但這會混亂我的代碼。不應該有排序的方式,不要嗆NSNull?畢竟,Apple已經明確提供了NSNull來允許我們將它包含在數組中。

回答

4

主要問題是NSNull在已知元素之前或之後排序爲什麼? - 沒有一般的答案 - 所以蘋果不能用通用的方法。

在你的情況下,你正在通過sortUsingDescriptors進行排序 - 這將從數組中的對象中獲取屬性「name」 - 對於NSNull,屬性「name」的值是什麼?

所以使用sortUsingDescriptors,你必須按照你的描述去除NSNull。

如果你想保留數組中的NSNull,你可以嘗試使用另一種方式排序 - sortUsingFunction:context:將允許你編寫一個可以處理NSNull的比較函數。 Apple代碼只需處理已知的對象,而不是它們包含的內容。

+4

甚至更​​好的是,你可以使用`sortUsingComparator:`進行排序,它需要一個`NSComparator`塊,並且可以節省在代碼中間添加不適當的功能。 – 2010-12-23 17:51:53

0

這就是我想出了爲itaiferber的建議(並使用蘋果公司的基礎數據類型參考)的結果:

我把這個在H文件:

typedef NSComparisonResult (^NSComparator)(id string1, id string2); 

我加入這個方法:

- (NSArray *) sortNullsToTopInStringArray:(NSArray *)array { 

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id string1, id string2) {  

    // First test for null object. It should go to top (beginning) of list. 
    if ([string1 class] == [NSNull class]) 
     return (NSComparisonResult)NSOrderedAscending; 

    if ([string2 class] == [NSNull class]) 
     return (NSComparisonResult)NSOrderedDescending; 

    // For non-null strings, use regular NSString compare method, and wrap it in NSComparisonResult. 
    switch ([string1 caseInsensitiveCompare:string2]) { 
     case NSOrderedAscending: 
      return (NSComparisonResult)NSOrderedAscending; 
     case NSOrderedSame: 
      return (NSComparisonResult)NSOrderedSame; 
     case NSOrderedDescending: 
      return (NSComparisonResult)NSOrderedDescending; 
     default: 
      return (NSComparisonResult)NSOrderedAscending; 
    } 

}]; 

return sortedArray; 
} 

,在這裏的:

NSArray *sortedArray = [self sortNullsToTopInStringArray:self.mutableArrayOfStrings]; 
NSMutableArray *sortedMutableArray = [sortedArray mutableCopy]; 
self.mutableArrayOfStrings = sortedMutableArray; 
[sortedMutableArray release]; 

對NSManagedObjects進行排序可以用同樣的方法完成,但爲了提取字符串,我必須爲每個實體類型提供不同的方法。

再次感謝Mark和itaiferber。

相關問題