从.plist NSDictionary中排序NSNumbers(分数)

时间:2011-11-18 12:24:41

标签: iphone objective-c sorting plist

我有一个带有NSDictionary类型的highscore.plist文件,每个项目包含5个项目,每个项目包含NSNumber - 得分和字符串 - 名称,

我想按降序排列分数。这就是我想要做的事情:

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(得分)时我没有做对。任何帮助,将不胜感激 。谢谢!

3 个答案:

答案 0 :(得分:1)

根据您的说明,highscoredataNSDictionary的数组。因此,调用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,知道如何比较自己。

答案 1 :(得分:0)

您传递给id num1的{​​{1}}和id num2似乎不是function intSort。它们似乎是NSDictionary对象。

答案 2 :(得分:0)

按降序对高分数据进行排序使用此代码

     NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO selector:@selector(localizedCompare:)];

      NSArray* sortedArray = [highScoreArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

这里我们使用localizedCompare:来比较字符串,并将NO传递给ascending:选项以按降序排序。