0

I know there are a whole bunch of questions that have been asked and answered in stackoverflow about the challenge of getting keys in an NSDictionary sorted by putting those keys into sort order in an array. I understand that objects are not stored in sort order within the actual dictionary and that is, I think, for reasons of efficiency or maybe memory management on the part of Foundation code.

I have been working on trying out examples from several answers out here and in apple documentation and blogs (some I can get to work, others not!) , but I can't seem to find an example that solves my confusion.

I think my confusion is that the examples I'm encountering both here, in apple documentation and in the different helpful blogs, all seem to have examples where there is just a key value pair and the second value is not an object - it's more like just a value. (However isn't it really an object at some level? I would think it is)

One example, that I couldn't get to work (Sorting an NSArray by an NSDictionary value ) , uses this idea

   [array sortedArrayUsingComparator:^(NSDictionary *item1, NSDictionary *item2) {
    NSString *age1 = [item1 objectForKey:@"age"];
    NSString *age2 = [item2 objectForKey:@"age"];
    return [age1 compare:age2 options:NSNumericSearch];
    }];

I thought maybe this idea, specifying the key in a more specific manner, might be my problem.

I wonder if maybe I'm not communicating to the compiler what the key is, and what the object is, and that is why I'm getting an "unrecognized selector sent to instance" error.

..... Code Snips Follow .....

1) I have a class called "Dog". A given dog object has several properties, including an NSString key.

My key is "licenseString" is an alphanumeric key - I'm also wondering if I should use decimalNumberWithString but that's not the question here

 @property (strong,nonatomic) NSString *licenseString;
  @property (strong, nonatomic) NSString *dogName;
 @property (strong, nonatomic) NSString *whatMakesDogSpecial;
 @property (strong, nonatomic) UIImage *dogPhoto;

2) I have an NSDictionary @property (nonatomic, strong) NSDictionary *dogDictionary;

I hardcode information into the dogDictionary in this not very sophisticated way,

 Dog *aDog;

// Dog one
aDog = [[Dog alloc]init] ;

aDog.licenseString     = @"1";
aDog.dogName   = @"Oscar";

aDog.whatMakesDogSpecial = @"This animal was found at the Mid-Penn humane society. He is super friendly, plays well with other dogs and likes people too. He enjoys fetching balls and frisbees too. He also goes to the park daily."   ;

aDog.dogPhoto   = [UIImage imageNamed:@"webVuMiniAppDogOscar.jpg"];

[self.dogDictionary setValue:aDog forKey:aDog.licenseString];

3) Then once I have several dog objects in my dogDictionary, I want to sort on the license tag values, so that I can populate a table view with dog names, but by order of their license tags.

BTW it seems that the compiler does recognize "vars.dogDictionary" which appears in the code snip below, because when I look at the debugger I can see that two valid instances are coming up from my dog dictionary. The debugger output is in an attachment

So, using ideas from a stackoverflow answer and the apple documentation, I write this

 NSArray *sortedKeys = [vars.dogDictionary keysSortedByValueUsingComparator:
                       ^NSComparisonResult(id obj1, id obj2) {
                           return [obj1 compare:obj2];
                       }];


NSLog(@" The sorted array is %@", sortedKeys);

And that's where my problem happens. I recognize that 0x1182f740 refers to "obj1" as shown in the debugger attachment

2013-08-06 15:13:58.276 SortDogLIcenseTags[3876:11303] -[Dog compare:]: unrecognized selector sent to instance 0x1182f740 (lldb)

Attachment is a picture showing debugger values - they don't like to paste very well

From the debugger - valid dog objects are showing up as obj1 and obj2 with properties I put in a

5
  • Not an Xcode question. -- As to the actual problem: google the error message, "unrecognized selector" is one of the most common (if not the most commmon) reasons why an Objective-C program may crash. Basically, you have to implement compare: on your Dog class. Commented Aug 6, 2013 at 22:56
  • Do you want a sorted array of keys (the licenseStrings)? Or a sorted array of dogs (sorted by the licenseString)? Also, what is vars? Commented Aug 6, 2013 at 23:21
  • Thanks. When you say it's not an Xcode question, how should I have labeled it? IOS? Objective-C? I will try to figure out how to implement compare on my class. I guess that is the difference between the examples I used from various sources? The classes they came from already had it? .... I was thinking I wanted a sorted array of keys - the license string, and that I would then choose dog objects from my dictionary based on the key, when I go to populate a master table view the user selects on. However, a sorted array of dogs might be good to know how to do as well Commented Aug 7, 2013 at 0:37
  • You should be sorting on NSString values, not the object in the array. Also, your NSString and NSDictionary properties are wrong, they need to be "copy" properties not "retain" which is what strong defaults to. Commented Aug 7, 2013 at 2:14
  • BTW I did not implement compare on my dog class. The sorted array I wanted was by the keys. I'm sorry my explanation of vars wasn't clear. Vars refers to a class where I keep all the apps data, like a corporate data source. Again I know this is not the most sophisticated way to do that. Commented Aug 11, 2013 at 1:27

1 Answer 1

0

Here's how I resolved this challenge. It works and was pretty straightforward to integrate into my Master/Detail project

I know I found a tutorial on the web somewhere that led me to this solution , I'm sorry I can't find it now.

Note that sortedDogDictionaryArray and dogDictionaryArray are declared as properties in the .h file.

self.dogDictionaryArray = [vars.dogDictionary allValues];
// Sort

NSSortDescriptor *sortDescriptorDog =
[[NSSortDescriptor alloc] initWithKey:@"licenseString" ascending:YES];
NSArray *sortDescriptorsDogs =
[NSArray arrayWithObject:sortDescriptorDog];


self.sortedDogDictionaryArray =
[self.dogDictionaryArray sortedArrayUsingDescriptors:sortDescriptorsDogs];
NSLog(@"%@",self.sortedDogDictionaryArray );

int doggie;
Dog *someDogName;
NSLog(@"Sorted Order is...");

for (doggie = 0; doggie < [self.sortedDogDictionaryArray count]; doggie++) {


    //NSLog(@"%@", [sortedArray objectAtIndex:i]);
    //NSLog(@"%@", [sortedArrayDogs objectAtIndex:doggie]);
    someDogName = [self.sortedDogDictionaryArray   objectAtIndex:doggie];
    //NSLog(@"name is %@", someDogName.dogName);
    NSLog(@"name is %@ tag is %@", someDogName.dogName, someDogName.licenseString);


}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.