0

Say I have the following block of code:

[allKeys sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSDictionary *firstArticle = [articles objectForKey:(NSString *)obj1];
    NSNumber *firstSortID = [firstArticle objectForKey:@"sort_id"];

    NSDictionary *secondArticle = [articles objectForKey:(NSString *)obj2];
    NSNumber *secondSortID = [secondArticle objectForKey:@"sort_id"];

    if (firstSortID == nil || secondSortID == nil) {
        return nil;
    }
    else {
        return [secondSortID compare:firstSortID];
    }
}];

I get the warning:

Incompatible pointer to integer conversion returning 'void *' from a function with result type 'NSComparisonResult' (aka 'enum NSComparisonResult')

But basically, if one of them is nil, it crashes because the comparison doesn't make sense. How do I tell it that if it's nil, don't bother, just stop.

4

2 回答 2

3

You have to decide how you want nil values to be sorted. Most likely they should go at the end of the list. You want something like this:

if (firstSortID) {
    if (secondSortID) {
        // Both set, compare
        NSComparisonResult result = [firstSortID compare:secondSortID];
        if (result == NSOrderedSame) {
            // optionally do another comparison on a secondary value
            // result = ...
        }
        return result;
    } else {
        // Have 1st but not 2nd
        return NSOrderedAscending;
    }
} else {
    if (secondSortID) {
       // Have 2nd but not 1st
       return NSOrderedDescending;
    } else {
       // Both nil, treat as the same
       // Another option here is to look at another value in the dictionary to be used as a secondary sort
       return NSOrderedSame;
    }
}
于 2013-09-01T21:01:14.263 回答
0

您不能使用sortUsingComparator:. 因此,您必须对nil值进行排序 - 只需决定是否nil应该是最小或最大值并返回NSOrderedDescendingNSOrderedAscending或者NSOrderedSame适当。

如果您需要知道是否点击了 anil然后在您的块中设置一个标志,您可以在之后进行测试。该标志需要使用__block限定符声明,以便可以在您的块中进行修改,例如:

__block BOOL nilFound = NO;
[allKeys sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
{
   NSDictionary *firstArticle = [articles objectForKey:(NSString *)obj1];
   NSNumber *firstSortID = [firstArticle objectForKey:@"sort_id"];

   NSDictionary *secondArticle = [articles objectForKey:(NSString *)obj2];
   NSNumber *secondSortID = [secondArticle objectForKey:@"sort_id"];

   // set flag - could alternatively be set during comparison logic below
   if (firstSortID == nil || secondSortID == nil)
      nilFound = YES;

   // actual comparison, allowing for nil values
   ...
}];

// was a nil found?
if (nilFound) ...

附录

其他人提出了稳定排序的问题,您应该能够通过使用原始键来解决这个问题,例如:

if (firstSortID == nil)
{
   if (secondSortID == nil)
   {
      // both nil - use original keys as secondary sort, obj1 & obj2 are strings
      return [obj1 compare:obj2];
   }
   else
      return NSSortAscending;
}
else
   return secondSortID == nil ? NSSortDescending : [secondSortID compare:firstSortID];

(您可以切换NSSortAscending&NSSortDescending以将nil值分组在另一端。)

于 2013-09-01T21:08:53.237 回答