2011-06-30 108 views
5

我有一個CoreData實體具有兩個屬性。一個叫'position',另一個叫'positionChange'。它們都是整數,位置屬性是當前位置,positionChange是前一個位置和新位置之間的差異。這意味着positionChange可能是負值。排序核心數據位置變化與排序描述符爲iPhone

現在我想按positionChange進行排序。但我希望它忽視負面價值。目前我正在對它進行降序排序,這會得出結果:2,1,0,-1,-2。 但我要找的是得到這個結果:2,-2,1,-1,0.

關於如何解決這個使用排序描述符的任何想法?


EDIT

我得到2類,一個稱爲的DataManager和另一種含有我的NSNumber類別(positionChange是類型的NSNumber的)。

在DataManager的我有一個方法叫「fetchData:」在那裏我執行與一種描述我的讀取請求:

NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:managedObjectContext]; 
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 

我做一些更多的東西的要求,但是這並不有趣爲這個問題。

我的NSNumber類別應完全像您發佈的一個: 在.H:

@interface NSNumber (AbsoluteValueSort) 
- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber; 
@end 

而在.M:

@implementation NSNumber (AbsoluteValueSort) 

- (NSComparisonResult)comparePositionChange:(NSNumber *)otherNumber 
{ 
    return [[NSNumber numberWithFloat:fabs([self floatValue])] compare:[NSNumber numberWithFloat:fabs([otherNumber floatValue])]]; 
} 

@end 

當我打電話fetchData我的DataManager對象我得到這個錯誤:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unsupported NSSortDescriptor selector: comparePositionChange:' 

任何想法可能是什麼情況?我在我的DataManager類中包含了我的NSNumber類別頭文件。

+0

你可以在模型中添加一個'absolutePositionChange'字段並用abs(positionChange)'填充它(在'positionChange'的setter中,如果有的話)?你可以在你的排序描述符中使用該字段。 –

回答

2

試試這個,假設你的positionChange是一個NSNumber:

@interface NSNumber (AbsoluteValueSort) 

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber; 

@end 

依次爲:

@implementation NSNumber (AbsoluteValueSort) 

-(NSComparisonResult) comparePositionChange:(NSNumber *)otherNumber 
{ 
    return [[NSNumber numberWithFloat: fabs([self floatValue])] compare:[NSNumber numberWithFloat: fabs([otherNumber floatValue])]]; 
} 

@end 

,然後做到這一點:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"positionChange" ascending:NO selector:@selector(comparePositionChange:)]; 

,並與描述符進行排序。如果你想讓-2總是在2之後,或者5總是在-5之後,你可以修改comparePositionChange:在一個數字是另一個數字的負數的情況下返回NSOrderedAscending。

+0

是否有可能調用對象之間的類別方法? 我的意思是我的排序描述符位於與NSNumber類別不同的​​類中。調用comparePositionChange:上面的示例不起作用。 你看到我的觀點了嗎? – Anonymous

+0

只要包含NSNumber類別的任何文件,它就可以工作。該類別不是「在」任何類別中。 – med200

+0

該類別位於NSNumber類中。用你的例子調用它意味着這個類是在NSSortDescriptor類中實現的。否則,應用程序將以NSInvalidArgumentException崩潰,原因是:'不支持的選擇器'。 在這種情況下,一個簡單的include將不起作用。除非我做錯了什麼。你測試過你的解決方案嗎? – Anonymous

5

代碼失敗並顯示unsupported NSSortDescriptor selector錯誤的原因是您正在使用SQLite數據存儲並嘗試使用Cocoa方法作爲排序描述符。使用SQLite存儲,排序描述符可以實時轉換爲SQL,並且通過SQLite進行排序。這確實有助於提高性能,但這也意味着排序是在不存在自定義比較方法的非Cocoa環境中完成的。這樣排序只適用於常用的已知方法,不適用於任意Cocoa代碼。

一個簡單的解決方法是在沒有排序的情況下執行讀取操作,獲取結果數組並對其進行排序。數組可以使用任何你想要的可可方法進行排序,所以med200的類別應該在那裏有用。

如果您的數據集不是很大,您也可以從SQLite數據存儲更改爲二進制存儲。