12

This is going to be something really stupid, but I have this code in my cellForRowAtIndexPath:

if ([self.indexPathSelected compare:indexPath] == NSOrderedSame)
{
    NSLog(@" %d %d %d %d", self.indexPathSelected.row, self.indexPathSelected.section, indexPath.row, indexPath.section);
}

This prints:

0 0 0 0

0 0 1 0

0 0 2 0

0 0 3 0

0 0 4 0

0 0 5 0

I was expecting it to only print 0 0 0 0.

What am I doing wrong here?

herzbube
  • 13,158
  • 9
  • 45
  • 87
Jason
  • 1,787
  • 4
  • 29
  • 46
  • 3
    Is `indexPathSelected` set to nil ? – Wain Jun 24 '13 at 15:34
  • Yes. Changing it to self.indexPathSelected = [NSIndexPath indexPathForRow:-1 inSection:-1]; fixed it. Two follow on questions, why does 'nil' not work? and second is setting it to -1, -1 the right fix? – Jason Jun 24 '13 at 15:39
  • 2
    Sending a message to nil will always result in nil => 0. Just check if you're comparing to nil. – Karl Jun 24 '13 at 15:44

2 Answers2

35

Since you're setting indexPathSelected to nil, you want to make sure it's non-nil before doing a compare.

if (self.indexPathSelected && [self.indexPathSelected compare:indexPath] == NSOrderedSame)
{
    NSLog(@" %d %d %d %d", self.indexPathSelected.row, self.indexPathSelected.section, indexPath.row, indexPath.section);
}

According to the documentation on NSIndexPath's compare method:

Parameters

indexPath

Index path to compare.

This value must not be nil. If the value is nil, the behavior is undefined.

Doc
  • 1,480
  • 2
  • 16
  • 28
  • 1
    Use `[indexPath compare:self.indexPathSelected]` instead, then you don't need to check if self.indexPathSelected is nil or not. – daisy May 27 '16 at 05:33
3

Interesting thing is that you can compare object like you compare pointers. But only on iPhone 5s and maybe higher. I have found this joke today). iOS on all devices was 8.1

Will work on iPhone 5s and higher: (will compare section and row)

if (optionsPath != pathForOptionsCellOfSelected)
//if ([optionsPath compare:pathForOptionsCellOfSelected] != NSOrderedSame)
{
    //if user selects cell under already selected, we do not need to shift index
    if (optionsPath.row < selectedRowIndexPath.row)
    {
        pathForOptionsCellOfSelected = selectedRowIndexPath;
    }
    [_tableView insertRowsAtIndexPaths:@[pathForOptionsCellOfSelected] withRowAnimation:UITableViewRowAnimationTop];
    optionsPath = [pathForOptionsCellOfSelected copy];
}

Anyway its not a good approach.

Mike Glukhov
  • 1,758
  • 19
  • 18