0

The following method:

- (NSMutableArray*) timeSortedBegins {
    NSMutableArray* begins = [self.spans valueForKey: @"begin"];
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey: @"cycleOffsetObject" ascending: YES];
    [begins sortUsingDescriptors: @[sort]];
    return begins;
}

throws this runtime exception:

2014-03-21 14:41:32.482 myValve[1741:60b] -[__NSArrayI sortUsingDescriptors:]: unrecognized selector sent to instance 0x16d7bc20
2014-03-21 14:41:32.484 myValve[1741:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI sortUsingDescriptors:]: unrecognized selector sent to instance 0x16d7bc20'

I have used breakpoints to convince myself that the begins array is indeed full of (two in this case) WEAnchor* objects. And that object implements the following two methods:

- (NSTimeInterval) cycleOffset {
    return self.offset + (self.datum ? self.datum.cycleOffset : 0.0);
}

- (NSNumber*) cycleOffsetObject {
    return [NSNumber numberWithDouble: self.cycleOffset];
}

To be honest, I only added the cycleOffsetObject wrapper method, because I thought maybe it couldn't work with non object values, I was using initWithKey: @"cycleOffset" before that. I have not declared these in the header file as a property, they're just accessor methods, not state. Is that the problem? If it is, how do you sort by the return value of a given selector? Or is it something head smackingly obvious that I'm just missing?

4
  • 1
    sortUsingDescriptor only works on a MUTABLE array. (And just because the pointer says "Mutable" does not make the array mutable.) Commented Mar 21, 2014 at 21:50
  • BTW, the -1 is for not having Googled "unrecognized selector". Commented Mar 21, 2014 at 22:04
  • I actually did google the whole thing, and read a bunch of things. My real error was assuming that it was something about the @"cycleOffset" and I totally glossed over that it was an __NSArrayI. Well actually, I did even notice that, but the toll free bridging/class cluster stuff that all the time, so I'm often not sure what I really have. I think I liked at the non-serif I', thought it was an 'l' and maybe stood for List or something. Commented Mar 22, 2014 at 0:11
  • But that's the main point of "unrecognized selector" -- the object type is almost always wrong. Had you studied any of the references you would have seen this. Commented Mar 22, 2014 at 2:48

2 Answers 2

10

As @dtrotzjr says, it sounds like your array is an immutable, not a mutable array.

You can either use mutableCopy to create a mutable copy and then sort that copy, or use the NSArray method sortedArrayUsingDescriptors: (which operates on an immutable array, and returns a sorted version of the contents as a second immutable array.)

To use mutableCopy, your code might look like this:

- (NSMutableArray*) timeSortedBegins {
    NSMutableArray* begins = [[self.spans valueForKey: @"begin"] mutableCopy];
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey: @"cycleOffsetObject" ascending: YES];
    [begins sortUsingDescriptors: @[sort]];
    return begins;
}
Sign up to request clarification or add additional context in comments.

Comments

4

Check that [self.spans valueForKey: @"begin"] is actually an NSMutableArray before casting it. The error message indicates that the pointer is actually an NSArray

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.