我有一个高分。NSDictionary,包含5个条目,每个条目包含NSNumber - score和String - Name,
我想对分数按降序排序。这就是我要做的:
NSString *location = [[NSBundle mainBundle] pathForResource:@"HighScores" ofType:@"plist"];
NSArray *highscoredata = [[NSArray alloc] initWithContentsOfFile:location];
self.sortedhighscores = [highscoredata sortedArrayUsingFunction:intSort context:0];
//intSort function :
NSInteger intSort(id num1, id num2, void *context) {
int v1 = [num1 intValue];
int v2 = [num2 intValue];
if (v1 < v2)
return NSOrderedAscending;
else if (v1 > v2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
这是我收到的错误:
2011-11-18 12:36:25.574 Test[27723:207] -[__NSCFDictionary intValue]: unrecognized selector sent to instance 0x4b66d50
2011-11-18 12:36:25.576 Test[27723:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary intValue]: unrecognized selector sent to instance 0x4b66d50'
*** Call stack at first throw:
(
0 CoreFoundation 0x00f355a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01089313 objc_exception_throw + 44
2 CoreFoundation 0x00f370bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00ea6966 ___forwarding___ + 966
4 CoreFoundation 0x00ea6522 _CF_forwarding_prep_0 + 50
5 Test 0x000035e8 intSort + 36
6 CoreFoundation 0x00e9c3cf __CFSimpleMergeSort + 591
7 CoreFoundation 0x00e9c1c6 __CFSimpleMergeSort + 70
8 CoreFoundation 0x00e9c06c CFSortIndexes + 268
9 CoreFoundation 0x00ebf42c -[NSArray sortedArrayWithOptions:usingComparator:] + 380
10 CoreFoundation 0x00ebf21a -[NSArray sortedArrayUsingFunction:context:] + 106
11 Test 0x000036f7 -[HighScore_ViewController viewDidLoad] + 192
12 UIKit 0x00372089 -[UIViewController view] + 179
13 UIKit 0x00373a3d -[UIViewController viewControllerForRotation] + 63
14 UIKit 0x0036f988 -[UIViewController _visibleView] + 90
15 UIKit 0x0061193c -[UIClientRotationContext initWithClient:toOrientation:duration:andWindow:] + 354
16 UIKit 0x002e981e -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 954
17 UIKit 0x00571619 -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 1381
18 UIKit 0x0037665d -[UIViewController presentModalViewController:withTransition:] + 3478
19 Test 0x0000296b -[Test_ViewController ShowLeaderboardsModal:] + 198
20 UIKit 0x002c24fd -[UIApplication sendAction:to:from:forEvent:] + 119
21 UIKit 0x00352799 -[UIControl sendAction:to:forEvent:] + 67
22 UIKit 0x00354c2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
23 UIKit 0x003537d8 -[UIControl touchesEnded:withEvent:] + 458
24 UIKit 0x002e6ded -[UIWindow _sendTouchesForEvent:] + 567
25 UIKit 0x002c7c37 -[UIApplication sendEvent:] + 447
26 UIKit 0x002ccf2e _UIApplicationHandleEvent + 7576
27 GraphicsServices 0x0188d992 PurpleEventCallback + 1550
28 CoreFoundation 0x00f16944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
29 CoreFoundation 0x00e76cf7 __CFRunLoopDoSource1 + 215
30 CoreFoundation 0x00e73f83 __CFRunLoopRun + 979
31 CoreFoundation 0x00e73840 CFRunLoopRunSpecific + 208
32 CoreFoundation 0x00e73761 CFRunLoopRunInMode + 97
33 GraphicsServices 0x0188c1c4 GSEventRunModal + 217
34 GraphicsServices 0x0188c289 GSEventRun + 115
35 UIKit 0x002d0c93 UIApplicationMain + 1160
36 Test 0x00001f3c main + 102
37 Test 0x00001ecd start + 53
)
terminate called after throwing an instance of 'NSException'
但是当我尝试在模拟器(iOS)上运行它时,它崩溃了,我是Objective C的新手,我认为我在比较数组中的NSNumber(分数)时没有做对。任何帮助都会很感激。谢谢!
根据您的描述,highscoredata
是NSDictionary
s的数组。所以调用sortedArrayUsingFunction:context
的结果是调用intSort
来比较字典。根据控制台报告的错误,NSDictionary
没有实现intValue
。
要直接调整代码,请尝试:
NSInteger intSort(id num1, id num2, void *context) {
// assuming the numerical score is in the dictionary
// under the key 'score'
int v1 = [[num1 objectForKey:@"score"] intValue];
int v2 = [[num2 objectForKey:@"score"] intValue];
...
那比较两个字典,从每个字典中检索NSNumber代表分数,然后比较那个
NSNumber实际上为自己实现了compare:
,所以更简洁的版本应该是:
NSInteger intSort(id num1, id num2, void *context) {
NSNumber *v1 = [num1 objectForKey:@"score"];
NSNumber *v2 = [num2 objectForKey:@"score"];
return [v1 compare:v2];
}
在此基础上,由于Objective-C中关键路径的工作方式,一个更短的版本将是:
NSArray *highscoredata = [[NSArray alloc] initWithContentsOfFile:location];
NSSortDescriptor *sortDescriptor =
[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES];
self.sortedhighscores = [highscoredata
sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
根本不需要intSort
函数- NSDictionary
知道如何查找关键"分数",而它查找的东西是NSNumber
s,它们知道如何比较自己。
按降序排序您的高分数据,使用以下代码
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:@selector(localizedCompare:)];
NSArray* sortedArray = [highScoreArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
这里我们使用localizedCompare:来比较字符串,并将NO传递给升序:选项来按降序排序。
您传递给function intSort
的id num1
和id num2
似乎不是NSNumber
。它们似乎是NSDictionary对象