Sorting NSNumbers(Scores) from .plist NSDictionary



我有一个高分。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(分数)时没有做对。任何帮助都会很感激。谢谢!

根据您的描述,highscoredataNSDictionary 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 intSortid num1id num2似乎不是NSNumber。它们似乎是NSDictionary对象

最新更新